@prestack/thread 0.1.2 → 0.1.4
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/CHANGELOG.md +193 -0
- package/dist/core/actor.d.ts +1 -1
- package/dist/core/actor.js +5 -4
- package/dist/core/actor.ts +5 -4
- package/dist/core/attach.d.ts +0 -7
- package/dist/core/attach.js +67 -58
- package/dist/core/attach.ts +61 -68
- package/dist/core/chain.js +13 -17
- package/dist/core/chain.ts +11 -15
- package/dist/core/condition.d.ts +4 -4
- package/dist/core/condition.js +2 -2
- package/dist/core/descend.d.ts +4 -2
- package/dist/core/descend.js +89 -21
- package/dist/core/descend.ts +86 -17
- package/dist/core/errors/catalogue.d.ts +52 -0
- package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
- package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
- package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
- package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
- package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
- package/dist/core/errors/namespaces.d.ts +3 -0
- package/dist/core/errors/namespaces.js +15 -0
- package/dist/core/errors/namespaces.ts +19 -0
- package/dist/core/finding.js +2 -2
- package/dist/core/finding.ts +1 -2
- package/dist/core/init.d.ts +0 -2
- package/dist/core/init.js +51 -15
- package/dist/core/init.ts +58 -15
- package/dist/core/invoked.d.ts +1 -1
- package/dist/core/invoked.js +3 -1
- package/dist/core/invoked.ts +5 -2
- package/dist/core/round.js +36 -22
- package/dist/core/round.ts +26 -9
- package/dist/core/rows.d.ts +4 -0
- package/dist/core/rows.js +31 -2
- package/dist/core/rows.ts +33 -1
- package/dist/core/thread.d.ts +3 -3
- package/dist/core/tree.d.ts +4 -1
- package/dist/core/tree.js +26 -6
- package/dist/core/tree.ts +29 -6
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +3 -1
- package/dist/core/types.ts +2 -1
- package/dist/derivation/attach.js +1 -1
- package/dist/derivation/generators/build.js +6 -6
- package/dist/derivation/generators/build.ts +1 -1
- package/dist/derivation/generators/check.js +1 -1
- package/dist/derivation/generators/determinism.js +1 -1
- package/dist/derivation/generators/release.js +60 -47
- package/dist/derivation/generators/release.ts +66 -43
- package/dist/derivation/release.d.ts +7 -3
- package/dist/derivation/release.js +14 -1
- package/dist/derivation/release.ts +22 -2
- package/dist/integrations/attach.d.ts +4 -0
- package/dist/integrations/attach.js +33 -54
- package/dist/integrations/attach.ts +50 -57
- package/dist/integrations/cli.d.ts +37 -0
- package/dist/integrations/cli.js +440 -0
- package/dist/integrations/cli.ts +543 -0
- package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -20
- package/dist/integrations/disk.js +435 -0
- package/dist/integrations/disk.ts +465 -0
- package/dist/integrations/generators/read.js +6 -6
- package/dist/integrations/generators/read.ts +4 -4
- package/dist/integrations/generators/vault.js +10 -11
- package/dist/integrations/generators/vault.ts +4 -5
- package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
- package/dist/integrations/https.js +170 -0
- package/dist/integrations/https.ts +216 -0
- package/dist/integrations/pglite.d.ts +26 -0
- package/dist/integrations/pglite.js +143 -0
- package/dist/integrations/pglite.ts +206 -0
- package/dist/integrations/secret.d.ts +8 -2
- package/dist/integrations/secret.js +3 -5
- package/dist/integrations/secret.ts +10 -6
- package/dist/integrations/target.d.ts +155 -14
- package/dist/integrations/target.js +171 -50
- package/dist/integrations/target.ts +377 -61
- package/dist/integrations/vault.d.ts +1 -0
- package/dist/integrations/vault.js +20 -5
- package/dist/integrations/vault.ts +17 -5
- package/dist/integrity/attach.js +3 -73
- package/dist/integrity/attach.ts +1 -71
- package/dist/integrity/check-threads.js +5 -5
- package/dist/integrity/check-threads.ts +2 -2
- package/dist/integrity/constraint.d.ts +0 -1
- package/dist/integrity/constraint.js +267 -366
- package/dist/integrity/constraint.ts +267 -375
- package/dist/integrity/generators/compiler.js +14 -17
- package/dist/integrity/generators/compiler.ts +10 -15
- package/dist/integrity/generators/gate.js +15 -15
- package/dist/integrity/generators/gate.ts +10 -10
- package/dist/integrity/generators/issues.js +7 -7
- package/dist/integrity/generators/publish.js +39 -57
- package/dist/integrity/generators/publish.ts +44 -55
- package/dist/integrity/generators/trial.d.ts +3 -3
- package/dist/integrity/generators/trial.js +133 -161
- package/dist/integrity/generators/trial.ts +145 -165
- package/dist/integrity/lint.js +9 -13
- package/dist/integrity/lint.ts +7 -10
- package/dist/integrity/lsp/bin.js +5 -4
- package/dist/integrity/lsp/bin.ts +3 -1
- package/dist/integrity/lsp/diagnostics.js +3 -3
- package/dist/integrity/lsp/diagnostics.ts +1 -1
- package/dist/integrity/lsp/lint.js +19 -30
- package/dist/integrity/lsp/lint.ts +16 -32
- package/dist/integrity/lsp/server.js +3 -3
- package/dist/integrity/slopnator.d.ts +3 -13
- package/dist/integrity/slopnator.js +58 -37
- package/dist/integrity/slopnator.ts +53 -37
- package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
- package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
- package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
- package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
- package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
- package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
- package/dist/integrity/slopnators/sl_inert_island.js +10 -8
- package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
- package/dist/integrity/slopnators/sl_missing_row.js +6 -51
- package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
- package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
- package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
- package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
- package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
- package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
- package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
- package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
- package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
- package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
- package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
- package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
- package/dist/integrity/slopnators/sl_stale_path.js +5 -22
- package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
- package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
- package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
- package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
- package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
- package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
- package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
- package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
- package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
- package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
- package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
- package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
- package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
- package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
- package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
- package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
- package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
- package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
- package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
- package/dist/integrity/slopnators/sl_underived_route.js +61 -0
- package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
- package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
- package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
- package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
- package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
- package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
- package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
- package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
- package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
- package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
- package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
- package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
- package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
- package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
- package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
- package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
- package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
- package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
- package/dist/integrity/slopnators/sl_unversioned.js +6 -4
- package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
- package/dist/integrity/sweep.d.ts +1 -0
- package/dist/integrity/sweep.js +105 -42
- package/dist/integrity/sweep.ts +115 -42
- package/dist/knowledge/attach.js +1 -1
- package/dist/knowledge/generators/docsgen.js +8 -6
- package/dist/knowledge/generators/docsgen.ts +4 -2
- package/dist/knowledge/generators/glossary.js +4 -4
- package/dist/knowledge/generators/glossary.ts +1 -1
- package/dist/operations/access.d.ts +23 -0
- package/dist/operations/access.js +28 -1
- package/dist/operations/access.ts +43 -0
- package/dist/operations/attach.js +28 -109
- package/dist/operations/attach.ts +46 -113
- package/dist/operations/capabilities.d.ts +14 -5
- package/dist/operations/capabilities.js +13 -4
- package/dist/operations/capabilities.ts +27 -8
- package/dist/operations/dispatch.d.ts +8 -2
- package/dist/operations/dispatch.js +128 -185
- package/dist/operations/dispatch.ts +138 -191
- package/dist/operations/error-results.d.ts +1 -1
- package/dist/operations/error-results.js +2 -2
- package/dist/operations/error-results.ts +2 -2
- package/dist/operations/generators/capability.d.ts +11 -1
- package/dist/operations/generators/capability.js +481 -224
- package/dist/operations/generators/capability.ts +562 -233
- package/dist/operations/generators/compile.js +66 -39
- package/dist/operations/generators/compile.ts +78 -39
- package/dist/operations/generators/permits.js +11 -12
- package/dist/operations/generators/permits.ts +3 -4
- package/dist/operations/generators/seed.d.ts +1 -0
- package/dist/operations/generators/seed.js +19 -17
- package/dist/operations/generators/seed.ts +22 -14
- package/dist/operations/generators/trial.d.ts +6 -8
- package/dist/operations/generators/trial.js +200 -70
- package/dist/operations/generators/trial.ts +230 -93
- package/dist/operations/nodes.d.ts +15 -16
- package/dist/operations/nodes.ts +16 -17
- package/dist/operations/operations.d.ts +40 -4
- package/dist/operations/operations.js +1 -0
- package/dist/operations/operations.ts +61 -4
- package/dist/operations/result.d.ts +2 -2
- package/dist/operations/result.ts +2 -2
- package/package.json +1 -4
- package/dist/core/answers.d.ts +0 -171
- package/dist/core/answers.js +0 -789
- package/dist/core/answers.ts +0 -999
- package/dist/core/client.d.ts +0 -57
- package/dist/core/client.js +0 -247
- package/dist/core/client.ts +0 -286
- package/dist/core/files.js +0 -145
- package/dist/core/files.ts +0 -193
- package/dist/integrations/module.d.ts +0 -6
- package/dist/integrations/module.js +0 -153
- package/dist/integrations/module.ts +0 -191
- package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
- package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
- package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
- package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
- package/dist/operations/cost.d.ts +0 -14
- package/dist/operations/cost.js +0 -37
- package/dist/operations/cost.ts +0 -58
- package/dist/operations/errors/errors.d.ts +0 -52
- package/dist/operations/http.js +0 -124
- package/dist/operations/http.ts +0 -169
- package/dist/operations/memory.d.ts +0 -104
- package/dist/operations/memory.js +0 -365
- package/dist/operations/memory.ts +0 -470
- package/dist/operations/metering.d.ts +0 -55
- package/dist/operations/metering.js +0 -247
- package/dist/operations/metering.ts +0 -328
- package/dist/operations/queue-policy.d.ts +0 -3
- package/dist/operations/queue-policy.js +0 -8
- package/dist/operations/queue-policy.ts +0 -10
- package/dist/operations/seams.d.ts +0 -239
- package/dist/operations/seams.js +0 -45
- package/dist/operations/seams.ts +0 -364
- package/dist/operations/store.d.ts +0 -14
- package/dist/operations/store.js +0 -1
- package/dist/operations/store.ts +0 -29
- /package/dist/{operations → core}/errors/classes.d.ts +0 -0
- /package/dist/{operations → core}/errors/classes.js +0 -0
- /package/dist/{operations → core}/errors/classes.ts +0 -0
- /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
- /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
|
@@ -36,6 +36,49 @@ export function undeclared(answered: string, offers: readonly string[], which: '
|
|
|
36
36
|
)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export interface Declaring {
|
|
40
|
+
readonly id: string
|
|
41
|
+
readonly holds: readonly { readonly id: string; readonly options?: readonly string[] }[]
|
|
42
|
+
readonly rows?: readonly Record<string, unknown>[]
|
|
43
|
+
readonly must?: readonly { readonly unique?: readonly string[] }[]
|
|
44
|
+
readonly actor?: { readonly roles: string; readonly entitlements?: string }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface Caller {
|
|
48
|
+
readonly id: string
|
|
49
|
+
readonly entity: string
|
|
50
|
+
readonly roles: readonly string[]
|
|
51
|
+
readonly entitlements: readonly string[]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const keyIn = (one: Declaring): string | undefined =>
|
|
55
|
+
(one.must ?? []).flatMap((each) => (each.unique?.length === 1 ? [each.unique[0] as string] : []))[0]
|
|
56
|
+
|
|
57
|
+
const wordsFrom = (held: unknown): readonly string[] => {
|
|
58
|
+
if (typeof held === 'string') return [held]
|
|
59
|
+
if (Array.isArray(held)) return held.filter((each): each is string => typeof each === 'string')
|
|
60
|
+
return []
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const declaredCallers = (entities: readonly Declaring[]): readonly Caller[] =>
|
|
64
|
+
entities.flatMap((one) => {
|
|
65
|
+
const said = one.actor
|
|
66
|
+
const key = keyIn(one)
|
|
67
|
+
if (said === undefined || key === undefined) return []
|
|
68
|
+
return (one.rows ?? []).flatMap((row): readonly Caller[] => {
|
|
69
|
+
const named = row[key]
|
|
70
|
+
if (typeof named !== 'string') return []
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
id: named,
|
|
74
|
+
entity: one.id,
|
|
75
|
+
roles: wordsFrom(row[said.roles]),
|
|
76
|
+
entitlements: said.entitlements === undefined ? [] : wordsFrom(row[said.entitlements]),
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
39
82
|
export interface Grant extends Member {
|
|
40
83
|
|
|
41
84
|
readonly may: readonly string[]
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { named } from
|
|
2
|
-
import { LISTS } from
|
|
3
|
-
import { quoted } from
|
|
4
|
-
import { PERMITS_AT } from
|
|
5
|
-
import { CAPABILITIES_AT, CLIENT_AT,
|
|
6
|
-
import { DISPATCH_AT } from
|
|
7
|
-
import { TRIALS_AT } from
|
|
8
|
-
import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from
|
|
9
|
-
import { SUPPLIES } from "./seams.js";
|
|
1
|
+
import { named } from '../core/scope.js';
|
|
2
|
+
import { LISTS } from '../core/descend.js';
|
|
3
|
+
import { quoted } from '../core/rows.js';
|
|
4
|
+
import { PERMITS_AT } from './access.js';
|
|
5
|
+
import { CAPABILITIES_AT, CLIENT_AT, DEFAULTS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT } from './capabilities.js';
|
|
6
|
+
import { DISPATCH_AT } from './dispatch.js';
|
|
7
|
+
import { TRIALS_AT } from './operations.js';
|
|
8
|
+
import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from './operations.js';
|
|
10
9
|
const HOME = `node_modules/${named('operations')}/dist`;
|
|
11
10
|
const VERSION = 1;
|
|
12
11
|
const ROOT = 'operations';
|
|
@@ -16,31 +15,13 @@ const DESCRIBES = 'Everything this app can be asked to do. Each operation is a n
|
|
|
16
15
|
export const TAKES = 'What one operation needs before it will run: the shape of its input, what it is expected to cost, and who is allowed to ask for it. Written once when the operation is created, then yours to change.';
|
|
17
16
|
export const WOVEN = 'The operation written out as one function. `thread compile` builds it from the steps declared for it, so nothing here is edited by hand — anything added here is gone the next time it is compiled.';
|
|
18
17
|
const NODES = 'Every kind of step an operation can be built from — a read, a branch, a loop. A step holds no code of its own: the work goes in a file written beside the operation that uses it.';
|
|
19
|
-
const HANDS = 'What each kind of step hands the code inside it to work with. These live in the package rather than in this app, so a step of the same kind means the same thing in every tree.';
|
|
20
18
|
const DISPATCH = 'Every operation runs through here and nowhere else. `thread compile` writes it for this app: before a run starts it checks who is asking, what the run may cost and whether the input is valid, then runs the operation and records what happened.';
|
|
21
19
|
const PROGRAM = 'Every row this package adds to an app, listed in one place so what it put there can be read rather than guessed at. `thread attach` writes back anything missing or edited.';
|
|
22
20
|
const TRIALS = 'What each operation actually did when it was run, recorded rather than written by hand. `thread trials` runs them against their example inputs and keeps the results; `thread trials --check` runs them again and refuses anything that has changed since.';
|
|
23
|
-
const CAPABILITIES = 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out
|
|
21
|
+
const CAPABILITIES = 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out, and nothing here is yours to set: which surfaces are on comes from _threads/defaults.ts and from `off` on each operation row, and `thread create capability` changes either.';
|
|
24
22
|
const OPENAPI = 'This app\'s web API written as an OpenAPI document: the route, the verb and the input shape of every operation that answers on the web. Generated rather than written, so it cannot describe a route that is not there.';
|
|
25
23
|
const TOOLS = 'The tools an MCP client is offered: every operation switched on for that surface, with its own sentence and the shape of its input. Switching `mcp` off for an operation is how an agent is told it may not call it.';
|
|
26
24
|
const CLIENT = 'Every operation a page in this app may call. An operation that is switched off is absent from this file rather than listed and disabled, as is any operation needing a credential a browser must not hold.';
|
|
27
|
-
const SAID = {
|
|
28
|
-
sm_store: 'Reading and writing rows. An operation that requires it is handed get, list, insert, update and remove already bound to whoever asked, so every row it touches is written under the caller the log names.',
|
|
29
|
-
sm_search: 'Indexing a row and querying an index. Required by an operation that has to find something it cannot address by id.',
|
|
30
|
-
sm_queue: 'Handing work to something else to run later. Required by an operation that finishes before its effect does.',
|
|
31
|
-
sm_events: 'Announcing that something happened, to whoever is listening. Required by an operation other parts of an app react to.',
|
|
32
|
-
sm_clock: 'The current time. Required rather than read off the runtime, because an operation that reads the wall clock directly cannot be replayed and its trial cannot be trusted.',
|
|
33
|
-
sm_random: 'Randomness. Required for the same reason as the clock: a run nobody can reproduce is a run nobody can check.',
|
|
34
|
-
sm_vault: 'Resolving a secret by name, for the rare thing that is not a call — signing a webhook, checking a shared token. An operation that reaches a target does not need this: requiring the target hands its nodes calls with the credential already in them, which is the whole point of declaring one.',
|
|
35
|
-
sm_views: 'Reading through a declared view rather than a table. Required by an operation that reads what somebody else composed.',
|
|
36
|
-
sm_files: 'Putting a file somewhere, fetching one back, or handing out a signed link to one. Required rather than reached for, because a node that opens a path directly is doing work no record names.',
|
|
37
|
-
};
|
|
38
|
-
const OFFERED = SUPPLIES.map((id) => ({
|
|
39
|
-
id,
|
|
40
|
-
at: NODES_AT,
|
|
41
|
-
describes: SAID[id],
|
|
42
|
-
version: VERSION,
|
|
43
|
-
}));
|
|
44
25
|
const valued = (one) => {
|
|
45
26
|
if (typeof one === 'string')
|
|
46
27
|
return quoted(one);
|
|
@@ -69,12 +50,20 @@ export const said = (one, pad) => {
|
|
|
69
50
|
};
|
|
70
51
|
const ACCESS = 'Who may ask this app to do what. A row says which operations it permits, on what, to whom, and under what condition. Nothing is permitted by default: an operation no row grants here cannot be run at all.';
|
|
71
52
|
const PERMITS = 'The check compiled from the grants in _threads/access.ts: one branch per grant, so who may ask for what comes from one statement. Nobody edits it, because an edit here widens or narrows access nobody granted. An app that grants nothing permits nothing.';
|
|
72
|
-
const SEAMS = 'What this app hands its operations, written once and then yours. It starts by handing on everything src/_generated/seams.ts settles from your declarations. Replace a seam or add one by naming it in SEAMS: the queue, the events, telemetry, whatever a real deployment needs.';
|
|
73
|
-
const DECLARED_SEAMS = 'The seams your declarations settle. Rows go to the store each target derived, and until one does no store is handed, so an operation that needs one is refused; who is calling is read off the entity that names the caller; calls leave through http with credentials the vault opens. Nobody edits it: `thread capabilities` writes it again from the rows.';
|
|
74
53
|
const ACCESS_SOURCE = `import type { Grant } from './access.ts'
|
|
75
54
|
|
|
76
55
|
export const GRANTS: readonly Grant[] = []
|
|
77
56
|
`;
|
|
57
|
+
const DEFAULTS = 'Which surfaces every operation in this app answers on, stated once for all of them. An operation turns one off with `off` on its own row and can never turn on one this row leaves off. With no `live` stated, every operation answers on cli alone, so nothing is reachable from outside the machine until this row says so. `thread create capability edit defaults` changes it.';
|
|
58
|
+
const DEFAULTS_SOURCE = `import type { Defaults } from './capabilities.ts'
|
|
59
|
+
|
|
60
|
+
export const DEFAULTS: Defaults = {
|
|
61
|
+
id: 'defaults',
|
|
62
|
+
at: ${quoted(DEFAULTS_AT)},
|
|
63
|
+
describes: ${quoted(DEFAULTS)},
|
|
64
|
+
version: ${String(VERSION)},
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
78
67
|
const shipped = () => ({
|
|
79
68
|
id: 'shipped',
|
|
80
69
|
at: `${HOME}/attach.js`,
|
|
@@ -99,6 +88,12 @@ const shipped = () => ({
|
|
|
99
88
|
describes: ACCESS,
|
|
100
89
|
version: VERSION,
|
|
101
90
|
},
|
|
91
|
+
{
|
|
92
|
+
id: 'defaults',
|
|
93
|
+
at: DEFAULTS_AT,
|
|
94
|
+
describes: DEFAULTS,
|
|
95
|
+
version: VERSION,
|
|
96
|
+
},
|
|
102
97
|
{
|
|
103
98
|
id: 'permits',
|
|
104
99
|
at: PERMITS_AT,
|
|
@@ -115,12 +110,6 @@ const shipped = () => ({
|
|
|
115
110
|
by: 'thread compile',
|
|
116
111
|
runs: 'thread compile --check',
|
|
117
112
|
},
|
|
118
|
-
{
|
|
119
|
-
id: 'hands',
|
|
120
|
-
at: `${HOME}/nodes.js`,
|
|
121
|
-
describes: HANDS,
|
|
122
|
-
version: VERSION,
|
|
123
|
-
},
|
|
124
113
|
{
|
|
125
114
|
id: 'trials',
|
|
126
115
|
at: TRIALS_AT,
|
|
@@ -169,21 +158,6 @@ const shipped = () => ({
|
|
|
169
158
|
by: 'thread capabilities',
|
|
170
159
|
runs: 'thread capabilities --check',
|
|
171
160
|
},
|
|
172
|
-
{
|
|
173
|
-
id: 'seams',
|
|
174
|
-
at: SEAMS_AT,
|
|
175
|
-
describes: SEAMS,
|
|
176
|
-
version: VERSION,
|
|
177
|
-
by: 'thread capabilities',
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
id: 'declared-seams',
|
|
181
|
-
at: DECLARED_SEAMS_AT,
|
|
182
|
-
describes: DECLARED_SEAMS,
|
|
183
|
-
version: VERSION,
|
|
184
|
-
by: 'thread capabilities',
|
|
185
|
-
runs: 'thread capabilities --check',
|
|
186
|
-
},
|
|
187
161
|
{
|
|
188
162
|
id: 'nd_read',
|
|
189
163
|
at: NODES_AT,
|
|
@@ -226,7 +200,6 @@ const shipped = () => ({
|
|
|
226
200
|
describes: 'A step that ends the operation early with an answer. Whatever its block returns becomes the result, and nothing after it runs.',
|
|
227
201
|
version: VERSION,
|
|
228
202
|
},
|
|
229
|
-
...OFFERED,
|
|
230
203
|
],
|
|
231
204
|
});
|
|
232
205
|
const SHIPS = shipped();
|
|
@@ -234,16 +207,15 @@ const WHERE = {
|
|
|
234
207
|
nodes: { into: OPERATIONS_FILE, list: 'declares' },
|
|
235
208
|
dispatch: { into: OPERATIONS_FILE, list: 'declares' },
|
|
236
209
|
access: { into: OPERATIONS_FILE, list: 'declares' },
|
|
210
|
+
defaults: { into: OPERATIONS_FILE, list: 'declares' },
|
|
237
211
|
permits: { into: OPERATIONS_FILE, list: 'declares' },
|
|
238
|
-
'declared-seams': { into: OPERATIONS_FILE, list: 'declares' },
|
|
239
212
|
trials: { into: OPERATIONS_FILE, list: 'declares' },
|
|
240
213
|
capabilities: { into: OPERATIONS_FILE, list: 'declares' },
|
|
241
214
|
openapi: { into: OPERATIONS_FILE, list: 'declares' },
|
|
242
215
|
tools: { into: OPERATIONS_FILE, list: 'declares' },
|
|
243
216
|
client: { into: OPERATIONS_FILE, list: 'declares' },
|
|
244
217
|
dispatching: { into: OPERATIONS_FILE, list: 'declares' },
|
|
245
|
-
|
|
246
|
-
hands: { into: NODES_FILE, list: 'declares' },
|
|
218
|
+
reaching: { into: OPERATIONS_FILE, list: 'declares' },
|
|
247
219
|
};
|
|
248
220
|
const placed = (id) => WHERE[id] ?? { into: NODES_FILE, list: MEMBERS_LIST };
|
|
249
221
|
const NODES_SOURCE = `import type { Threaded } from '../core/thread.ts'
|
|
@@ -323,60 +295,7 @@ export const ATTACH = {
|
|
|
323
295
|
{ file: OPERATIONS_FILE, source: OPERATIONS_SOURCE },
|
|
324
296
|
{ file: NODES_FILE, source: NODES_SOURCE },
|
|
325
297
|
{ file: 'access.ts', source: ACCESS_SOURCE },
|
|
326
|
-
|
|
327
|
-
retires: [
|
|
328
|
-
{
|
|
329
|
-
into: 'operations.ts',
|
|
330
|
-
list: 'declares',
|
|
331
|
-
id: 'reference',
|
|
332
|
-
made: `${ROOT}/_docs.md`,
|
|
333
|
-
why: `the page stating what this app declares is written by \`${named('knowledge')}\` now, at docs.md, and it states every node rather than operations alone — a package documenting what another package declares would be one package authoring another's`,
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
into: 'derivation.ts',
|
|
337
|
-
list: 'GENERATORS',
|
|
338
|
-
id: 'create-generator',
|
|
339
|
-
why: '`thread create` is a command of the CLI itself now, so no row declares it. This package still makes operations, through the `operation-noun` row beside this one',
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
into: 'operations.ts',
|
|
343
|
-
list: 'declares',
|
|
344
|
-
id: 'identity',
|
|
345
|
-
made: `src/identity.${'ts'}`,
|
|
346
|
-
why: 'who is calling is answered in `src/seams.ts` now, beside the store it reads the caller\'s row from. One derived file says both, because both are read off the same rows',
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
into: 'operations.ts',
|
|
350
|
-
list: 'declares',
|
|
351
|
-
id: 'store',
|
|
352
|
-
made: `src/store.${'ts'}`,
|
|
353
|
-
why: 'where rows go is decided in `src/seams.ts` now, read off the targets this app declares. A second file that only re-exported one name said nothing the seams did not',
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
into: 'operations.ts',
|
|
357
|
-
list: 'declares',
|
|
358
|
-
id: 'rules-gate',
|
|
359
|
-
made: `src/rules.${'ts'}`,
|
|
360
|
-
why: '`rules` is what this app refuses, declared in _threads/rules.ts with `thread create rule`. Who may ask for what is `permits`, compiled from the grants and handed to dispatch by src/_generated/seams.ts, so a second file wearing the word said nothing the grants did not',
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
into: 'derivation.ts',
|
|
364
|
-
list: 'GENERATORS',
|
|
365
|
-
id: 'rules-generator',
|
|
366
|
-
why: 'the check compiled from the grants is `permits`, and `thread permits` writes it now, through the `permits-generator` row beside this one. A generator called `rules` read as the app\'s own rules, which are declared in _threads/rules.ts with `thread create rule`',
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
into: NODES_FILE,
|
|
370
|
-
list: MEMBERS_LIST,
|
|
371
|
-
id: 'sm_http',
|
|
372
|
-
why: 'a call goes to a place, and a place is a target — declare it with `thread create target` and require that instead. Asking for a bare transport is what made an operation impossible to try, because nothing said where it went',
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
into: NODES_FILE,
|
|
376
|
-
list: MEMBERS_LIST,
|
|
377
|
-
id: 'sm_llm',
|
|
378
|
-
why: 'a model is reached over https like any other vendor, so it is an `ht_` target with its calls declared beside it. Nothing was lost: its address and its key are now under the same rules as every other credential, and an operation that asks a model can now be tried',
|
|
379
|
-
},
|
|
298
|
+
{ file: 'defaults.ts', source: DEFAULTS_SOURCE },
|
|
380
299
|
],
|
|
381
300
|
rows: [
|
|
382
301
|
...(SHIPS.declares ?? [])
|
|
@@ -6,11 +6,10 @@ import { quoted } from '../core/rows.ts'
|
|
|
6
6
|
import type { Threaded } from '../core/thread.ts'
|
|
7
7
|
|
|
8
8
|
import { PERMITS_AT } from './access.ts'
|
|
9
|
-
import { CAPABILITIES_AT, CLIENT_AT,
|
|
9
|
+
import { CAPABILITIES_AT, CLIENT_AT, DEFAULTS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT } from './capabilities.ts'
|
|
10
10
|
import { DISPATCH_AT } from './dispatch.ts'
|
|
11
11
|
import { TRIALS_AT } from './operations.ts'
|
|
12
12
|
import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from './operations.ts'
|
|
13
|
-
import { SUPPLIES, type Supplied } from './seams.ts'
|
|
14
13
|
|
|
15
14
|
const HOME = `node_modules/${named('operations')}/dist`
|
|
16
15
|
|
|
@@ -34,9 +33,6 @@ export const WOVEN =
|
|
|
34
33
|
const NODES =
|
|
35
34
|
'Every kind of step an operation can be built from — a read, a branch, a loop. A step holds no code of its own: the work goes in a file written beside the operation that uses it.'
|
|
36
35
|
|
|
37
|
-
const HANDS =
|
|
38
|
-
'What each kind of step hands the code inside it to work with. These live in the package rather than in this app, so a step of the same kind means the same thing in every tree.'
|
|
39
|
-
|
|
40
36
|
const DISPATCH =
|
|
41
37
|
'Every operation runs through here and nowhere else. `thread compile` writes it for this app: before a run starts it checks who is asking, what the run may cost and whether the input is valid, then runs the operation and records what happened.'
|
|
42
38
|
|
|
@@ -47,7 +43,7 @@ const TRIALS =
|
|
|
47
43
|
'What each operation actually did when it was run, recorded rather than written by hand. `thread trials` runs them against their example inputs and keeps the results; `thread trials --check` runs them again and refuses anything that has changed since.'
|
|
48
44
|
|
|
49
45
|
const CAPABILITIES =
|
|
50
|
-
'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out
|
|
46
|
+
'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out, and nothing here is yours to set: which surfaces are on comes from _threads/defaults.ts and from `off` on each operation row, and `thread create capability` changes either.'
|
|
51
47
|
|
|
52
48
|
const OPENAPI =
|
|
53
49
|
'This app\'s web API written as an OpenAPI document: the route, the verb and the input shape of every operation that answers on the web. Generated rather than written, so it cannot describe a route that is not there.'
|
|
@@ -58,28 +54,28 @@ const TOOLS =
|
|
|
58
54
|
const CLIENT =
|
|
59
55
|
'Every operation a page in this app may call. An operation that is switched off is absent from this file rather than listed and disabled, as is any operation needing a credential a browser must not hold.'
|
|
60
56
|
|
|
61
|
-
const SAID: Readonly<Record<Supplied, string>> = {
|
|
62
|
-
sm_store:
|
|
63
|
-
'Reading and writing rows. An operation that requires it is handed get, list, insert, update and remove already bound to whoever asked, so every row it touches is written under the caller the log names.',
|
|
64
|
-
sm_search: 'Indexing a row and querying an index. Required by an operation that has to find something it cannot address by id.',
|
|
65
|
-
sm_queue: 'Handing work to something else to run later. Required by an operation that finishes before its effect does.',
|
|
66
|
-
sm_events: 'Announcing that something happened, to whoever is listening. Required by an operation other parts of an app react to.',
|
|
67
|
-
sm_clock:
|
|
68
|
-
'The current time. Required rather than read off the runtime, because an operation that reads the wall clock directly cannot be replayed and its trial cannot be trusted.',
|
|
69
|
-
sm_random: 'Randomness. Required for the same reason as the clock: a run nobody can reproduce is a run nobody can check.',
|
|
70
|
-
sm_vault:
|
|
71
|
-
'Resolving a secret by name, for the rare thing that is not a call — signing a webhook, checking a shared token. An operation that reaches a target does not need this: requiring the target hands its nodes calls with the credential already in them, which is the whole point of declaring one.',
|
|
72
|
-
sm_views: 'Reading through a declared view rather than a table. Required by an operation that reads what somebody else composed.',
|
|
73
|
-
sm_files:
|
|
74
|
-
'Putting a file somewhere, fetching one back, or handing out a signed link to one. Required rather than reached for, because a node that opens a path directly is doing work no record names.',
|
|
75
|
-
}
|
|
76
57
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
83
79
|
|
|
84
80
|
const valued = (one: unknown): string => {
|
|
85
81
|
if (typeof one === 'string') return quoted(one)
|
|
@@ -110,17 +106,24 @@ const ACCESS =
|
|
|
110
106
|
const PERMITS =
|
|
111
107
|
'The check compiled from the grants in _threads/access.ts: one branch per grant, so who may ask for what comes from one statement. Nobody edits it, because an edit here widens or narrows access nobody granted. An app that grants nothing permits nothing.'
|
|
112
108
|
|
|
113
|
-
const SEAMS =
|
|
114
|
-
'What this app hands its operations, written once and then yours. It starts by handing on everything src/_generated/seams.ts settles from your declarations. Replace a seam or add one by naming it in SEAMS: the queue, the events, telemetry, whatever a real deployment needs.'
|
|
115
|
-
|
|
116
|
-
const DECLARED_SEAMS =
|
|
117
|
-
'The seams your declarations settle. Rows go to the store each target derived, and until one does no store is handed, so an operation that needs one is refused; who is calling is read off the entity that names the caller; calls leave through http with credentials the vault opens. Nobody edits it: `thread capabilities` writes it again from the rows.'
|
|
118
|
-
|
|
119
109
|
const ACCESS_SOURCE = `import type { Grant } from './access.ts'
|
|
120
110
|
|
|
121
111
|
export const GRANTS: readonly Grant[] = []
|
|
122
112
|
`
|
|
123
113
|
|
|
114
|
+
const DEFAULTS =
|
|
115
|
+
'Which surfaces every operation in this app answers on, stated once for all of them. An operation turns one off with `off` on its own row and can never turn on one this row leaves off. With no `live` stated, every operation answers on cli alone, so nothing is reachable from outside the machine until this row says so. `thread create capability edit defaults` changes it.'
|
|
116
|
+
|
|
117
|
+
const DEFAULTS_SOURCE = `import type { Defaults } from './capabilities.ts'
|
|
118
|
+
|
|
119
|
+
export const DEFAULTS: Defaults = {
|
|
120
|
+
id: 'defaults',
|
|
121
|
+
at: ${quoted(DEFAULTS_AT)},
|
|
122
|
+
describes: ${quoted(DEFAULTS)},
|
|
123
|
+
version: ${String(VERSION)},
|
|
124
|
+
}
|
|
125
|
+
`
|
|
126
|
+
|
|
124
127
|
const shipped = (): Threaded => ({
|
|
125
128
|
id: 'shipped',
|
|
126
129
|
at: `${HOME}/attach.js`,
|
|
@@ -145,6 +148,12 @@ const shipped = (): Threaded => ({
|
|
|
145
148
|
describes: ACCESS,
|
|
146
149
|
version: VERSION,
|
|
147
150
|
},
|
|
151
|
+
{
|
|
152
|
+
id: 'defaults',
|
|
153
|
+
at: DEFAULTS_AT,
|
|
154
|
+
describes: DEFAULTS,
|
|
155
|
+
version: VERSION,
|
|
156
|
+
},
|
|
148
157
|
{
|
|
149
158
|
id: 'permits',
|
|
150
159
|
at: PERMITS_AT,
|
|
@@ -161,12 +170,6 @@ const shipped = (): Threaded => ({
|
|
|
161
170
|
by: 'thread compile',
|
|
162
171
|
runs: 'thread compile --check',
|
|
163
172
|
},
|
|
164
|
-
{
|
|
165
|
-
id: 'hands',
|
|
166
|
-
at: `${HOME}/nodes.js`,
|
|
167
|
-
describes: HANDS,
|
|
168
|
-
version: VERSION,
|
|
169
|
-
},
|
|
170
173
|
{
|
|
171
174
|
id: 'trials',
|
|
172
175
|
at: TRIALS_AT,
|
|
@@ -217,21 +220,6 @@ const shipped = (): Threaded => ({
|
|
|
217
220
|
by: 'thread capabilities',
|
|
218
221
|
runs: 'thread capabilities --check',
|
|
219
222
|
},
|
|
220
|
-
{
|
|
221
|
-
id: 'seams',
|
|
222
|
-
at: SEAMS_AT,
|
|
223
|
-
describes: SEAMS,
|
|
224
|
-
version: VERSION,
|
|
225
|
-
by: 'thread capabilities',
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
id: 'declared-seams',
|
|
229
|
-
at: DECLARED_SEAMS_AT,
|
|
230
|
-
describes: DECLARED_SEAMS,
|
|
231
|
-
version: VERSION,
|
|
232
|
-
by: 'thread capabilities',
|
|
233
|
-
runs: 'thread capabilities --check',
|
|
234
|
-
},
|
|
235
223
|
{
|
|
236
224
|
id: 'nd_read',
|
|
237
225
|
at: NODES_AT,
|
|
@@ -274,7 +262,7 @@ const shipped = (): Threaded => ({
|
|
|
274
262
|
describes: 'A step that ends the operation early with an answer. Whatever its block returns becomes the result, and nothing after it runs.',
|
|
275
263
|
version: VERSION,
|
|
276
264
|
},
|
|
277
|
-
|
|
265
|
+
|
|
278
266
|
],
|
|
279
267
|
})
|
|
280
268
|
|
|
@@ -285,16 +273,15 @@ const WHERE: Readonly<Record<string, { readonly into: string; readonly list: str
|
|
|
285
273
|
|
|
286
274
|
dispatch: { into: OPERATIONS_FILE, list: 'declares' },
|
|
287
275
|
access: { into: OPERATIONS_FILE, list: 'declares' },
|
|
276
|
+
defaults: { into: OPERATIONS_FILE, list: 'declares' },
|
|
288
277
|
permits: { into: OPERATIONS_FILE, list: 'declares' },
|
|
289
|
-
'declared-seams': { into: OPERATIONS_FILE, list: 'declares' },
|
|
290
278
|
trials: { into: OPERATIONS_FILE, list: 'declares' },
|
|
291
279
|
capabilities: { into: OPERATIONS_FILE, list: 'declares' },
|
|
292
280
|
openapi: { into: OPERATIONS_FILE, list: 'declares' },
|
|
293
281
|
tools: { into: OPERATIONS_FILE, list: 'declares' },
|
|
294
282
|
client: { into: OPERATIONS_FILE, list: 'declares' },
|
|
295
283
|
dispatching: { into: OPERATIONS_FILE, list: 'declares' },
|
|
296
|
-
|
|
297
|
-
hands: { into: NODES_FILE, list: 'declares' },
|
|
284
|
+
reaching: { into: OPERATIONS_FILE, list: 'declares' },
|
|
298
285
|
}
|
|
299
286
|
|
|
300
287
|
const placed = (id: string): { readonly into: string; readonly list: string } =>
|
|
@@ -381,63 +368,9 @@ export const ATTACH: Attaching = {
|
|
|
381
368
|
{ file: NODES_FILE, source: NODES_SOURCE },
|
|
382
369
|
|
|
383
370
|
{ file: 'access.ts', source: ACCESS_SOURCE },
|
|
371
|
+
{ file: 'defaults.ts', source: DEFAULTS_SOURCE },
|
|
384
372
|
],
|
|
385
373
|
|
|
386
|
-
retires: [
|
|
387
|
-
{
|
|
388
|
-
into: 'operations.ts',
|
|
389
|
-
list: 'declares',
|
|
390
|
-
id: 'reference',
|
|
391
|
-
made: `${ROOT}/_docs.md`,
|
|
392
|
-
why: `the page stating what this app declares is written by \`${named('knowledge')}\` now, at docs.md, and it states every node rather than operations alone — a package documenting what another package declares would be one package authoring another's`,
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
into: 'derivation.ts',
|
|
396
|
-
list: 'GENERATORS',
|
|
397
|
-
id: 'create-generator',
|
|
398
|
-
why: '`thread create` is a command of the CLI itself now, so no row declares it. This package still makes operations, through the `operation-noun` row beside this one',
|
|
399
|
-
},
|
|
400
|
-
{
|
|
401
|
-
into: 'operations.ts',
|
|
402
|
-
list: 'declares',
|
|
403
|
-
id: 'identity',
|
|
404
|
-
made: `src/identity.${'ts'}`,
|
|
405
|
-
why: 'who is calling is answered in `src/seams.ts` now, beside the store it reads the caller\'s row from. One derived file says both, because both are read off the same rows',
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
into: 'operations.ts',
|
|
409
|
-
list: 'declares',
|
|
410
|
-
id: 'store',
|
|
411
|
-
made: `src/store.${'ts'}`,
|
|
412
|
-
why: 'where rows go is decided in `src/seams.ts` now, read off the targets this app declares. A second file that only re-exported one name said nothing the seams did not',
|
|
413
|
-
},
|
|
414
|
-
{
|
|
415
|
-
into: 'operations.ts',
|
|
416
|
-
list: 'declares',
|
|
417
|
-
id: 'rules-gate',
|
|
418
|
-
made: `src/rules.${'ts'}`,
|
|
419
|
-
why: '`rules` is what this app refuses, declared in _threads/rules.ts with `thread create rule`. Who may ask for what is `permits`, compiled from the grants and handed to dispatch by src/_generated/seams.ts, so a second file wearing the word said nothing the grants did not',
|
|
420
|
-
},
|
|
421
|
-
{
|
|
422
|
-
into: 'derivation.ts',
|
|
423
|
-
list: 'GENERATORS',
|
|
424
|
-
id: 'rules-generator',
|
|
425
|
-
why: 'the check compiled from the grants is `permits`, and `thread permits` writes it now, through the `permits-generator` row beside this one. A generator called `rules` read as the app\'s own rules, which are declared in _threads/rules.ts with `thread create rule`',
|
|
426
|
-
},
|
|
427
|
-
|
|
428
|
-
{
|
|
429
|
-
into: NODES_FILE,
|
|
430
|
-
list: MEMBERS_LIST,
|
|
431
|
-
id: 'sm_http',
|
|
432
|
-
why: 'a call goes to a place, and a place is a target — declare it with `thread create target` and require that instead. Asking for a bare transport is what made an operation impossible to try, because nothing said where it went',
|
|
433
|
-
},
|
|
434
|
-
{
|
|
435
|
-
into: NODES_FILE,
|
|
436
|
-
list: MEMBERS_LIST,
|
|
437
|
-
id: 'sm_llm',
|
|
438
|
-
why: 'a model is reached over https like any other vendor, so it is an `ht_` target with its calls declared beside it. Nothing was lost: its address and its key are now under the same rules as every other credential, and an operation that asks a model can now be tried',
|
|
439
|
-
},
|
|
440
|
-
],
|
|
441
374
|
rows: [
|
|
442
375
|
...(SHIPS.declares ?? [])
|
|
443
376
|
.filter((one) => one.id !== ROOT)
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Threaded } from '../core/thread.ts';
|
|
2
|
+
export declare const SURFACES: readonly ['cli', 'api', 'mcp', 'webhook'];
|
|
2
3
|
export type Surface = (typeof SURFACES)[number];
|
|
3
4
|
export declare const isSurface: (one: string) => one is Surface;
|
|
5
|
+
export declare const MEANS: Readonly<Record<Surface, string>>;
|
|
6
|
+
export declare const DEFAULTS_AT = "_threads/defaults.ts";
|
|
7
|
+
export declare const UNSTATED: readonly Surface[];
|
|
8
|
+
export interface Defaults extends Threaded {
|
|
9
|
+
readonly live?: readonly Surface[];
|
|
10
|
+
}
|
|
4
11
|
export declare const CAPABILITIES_AT = "operations/_capabilities.json";
|
|
5
12
|
export declare const CLIENT_AT = "operations/_client.ts";
|
|
6
13
|
export declare const DISPATCHING_AT = "app/_generated/dispatching.ts";
|
|
14
|
+
export declare const REACHING_AT = "src/_generated/reaching.ts";
|
|
15
|
+
export declare const ACTOR_AT = "src/_generated/actor.ts";
|
|
7
16
|
export declare const routeAt: (operation: string) => string;
|
|
8
|
-
export declare const ROUTE = "The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch with
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const DECLARED_SEAMS_AT = "src/_generated/seams.ts";
|
|
17
|
+
export declare const ROUTE = "The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch along with what this app hands its operations and the caller worked out from the request, and answers with the result \u2014 or with the status matching whatever dispatch refused it for. One per operation rather than one for all of them: a route that looked its operation up by a name off the path would hand dispatch something no check had ever seen, which reads exactly like a name that was checked. An operation that does not answer on api, because its own row turns api off or the defaults sheet leaves it off, has neither this file nor this row: `thread capabilities` takes both out, so it is not served at all rather than served and turned away.";
|
|
18
|
+
export declare const inboundAt: (webhook: string) => string;
|
|
11
19
|
export declare const OPENAPI_AT = "operations/_openapi.json";
|
|
12
20
|
export declare const MCP_AT = "operations/_mcp.json";
|
|
13
21
|
export interface Capability {
|
|
@@ -17,8 +25,9 @@ export interface Capability {
|
|
|
17
25
|
readonly nodes: readonly string[];
|
|
18
26
|
readonly input: unknown;
|
|
19
27
|
readonly live: readonly Surface[];
|
|
28
|
+
readonly webhooks: readonly string[];
|
|
29
|
+
readonly signed: boolean;
|
|
20
30
|
readonly browsable: boolean;
|
|
21
|
-
readonly local: boolean;
|
|
22
31
|
readonly mcp: {
|
|
23
32
|
readonly name: string;
|
|
24
33
|
readonly description: string;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
export const SURFACES = ['cli', 'api', 'mcp'];
|
|
1
|
+
export const SURFACES = ['cli', 'api', 'mcp', 'webhook'];
|
|
2
2
|
export const isSurface = (one) => SURFACES.includes(one);
|
|
3
|
+
export const MEANS = {
|
|
4
|
+
cli: 'a command a terminal runs',
|
|
5
|
+
api: 'a route a request arrives on, and the OpenAPI document written from it. An operation that does not answer on api has no route file and no route row at all',
|
|
6
|
+
mcp: 'a tool an agent is offered. Switch this off and an AI actor cannot call the operation, while everything else about it goes on working',
|
|
7
|
+
webhook: 'an address something outside posts to, once a webhook row invokes the operation and the operation names it back',
|
|
8
|
+
};
|
|
9
|
+
export const DEFAULTS_AT = '_threads/defaults.ts';
|
|
10
|
+
export const UNSTATED = ['cli'];
|
|
3
11
|
export const CAPABILITIES_AT = 'operations/_capabilities.json';
|
|
4
12
|
export const CLIENT_AT = 'operations/_client.ts';
|
|
5
13
|
export const DISPATCHING_AT = 'app/_generated/dispatching.ts';
|
|
14
|
+
export const REACHING_AT = 'src/_generated/reaching.ts';
|
|
15
|
+
export const ACTOR_AT = 'src/_generated/actor.ts';
|
|
6
16
|
export const routeAt = (operation) => `app/operations/${operation}/route.ts`;
|
|
7
|
-
export const ROUTE =
|
|
8
|
-
export const
|
|
9
|
-
export const DECLARED_SEAMS_AT = 'src/_generated/seams.ts';
|
|
17
|
+
export const ROUTE = "The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch along with what this app hands its operations and the caller worked out from the request, and answers with the result — or with the status matching whatever dispatch refused it for. One per operation rather than one for all of them: a route that looked its operation up by a name off the path would hand dispatch something no check had ever seen, which reads exactly like a name that was checked. An operation that does not answer on api, because its own row turns api off or the defaults sheet leaves it off, has neither this file nor this row: `thread capabilities` takes both out, so it is not served at all rather than served and turned away.";
|
|
18
|
+
export const inboundAt = (webhook) => `app/inbound/${webhook}/route.ts`;
|
|
10
19
|
export const OPENAPI_AT = 'operations/_openapi.json';
|
|
11
20
|
export const MCP_AT = 'operations/_mcp.json';
|
|
12
21
|
export const reachable = (one, surface) => one.live.includes(surface);
|
|
@@ -1,25 +1,42 @@
|
|
|
1
|
+
import type { Threaded } from '../core/thread.ts'
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
export const SURFACES = ['cli', 'api', 'mcp'] as const
|
|
3
|
+
export const SURFACES = ['cli', 'api', 'mcp', 'webhook'] as const
|
|
4
4
|
|
|
5
5
|
export type Surface = (typeof SURFACES)[number]
|
|
6
6
|
|
|
7
7
|
export const isSurface = (one: string): one is Surface => (SURFACES as readonly string[]).includes(one)
|
|
8
8
|
|
|
9
|
+
export const MEANS: Readonly<Record<Surface, string>> = {
|
|
10
|
+
cli: 'a command a terminal runs',
|
|
11
|
+
api: 'a route a request arrives on, and the OpenAPI document written from it. An operation that does not answer on api has no route file and no route row at all',
|
|
12
|
+
mcp: 'a tool an agent is offered. Switch this off and an AI actor cannot call the operation, while everything else about it goes on working',
|
|
13
|
+
webhook: 'an address something outside posts to, once a webhook row invokes the operation and the operation names it back',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const DEFAULTS_AT = '_threads/defaults.ts'
|
|
17
|
+
|
|
18
|
+
export const UNSTATED: readonly Surface[] = ['cli']
|
|
19
|
+
|
|
20
|
+
export interface Defaults extends Threaded {
|
|
21
|
+
readonly live?: readonly Surface[]
|
|
22
|
+
}
|
|
23
|
+
|
|
9
24
|
export const CAPABILITIES_AT = 'operations/_capabilities.json'
|
|
10
25
|
|
|
11
26
|
export const CLIENT_AT = 'operations/_client.ts'
|
|
12
27
|
|
|
13
28
|
export const DISPATCHING_AT = 'app/_generated/dispatching.ts'
|
|
14
29
|
|
|
30
|
+
export const REACHING_AT = 'src/_generated/reaching.ts'
|
|
31
|
+
|
|
32
|
+
export const ACTOR_AT = 'src/_generated/actor.ts'
|
|
33
|
+
|
|
15
34
|
export const routeAt = (operation: string): string => `app/operations/${operation}/route.ts`
|
|
16
35
|
|
|
17
36
|
export const ROUTE =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export const SEAMS_AT = 'src/seams.ts'
|
|
37
|
+
"The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch along with what this app hands its operations and the caller worked out from the request, and answers with the result — or with the status matching whatever dispatch refused it for. One per operation rather than one for all of them: a route that looked its operation up by a name off the path would hand dispatch something no check had ever seen, which reads exactly like a name that was checked. An operation that does not answer on api, because its own row turns api off or the defaults sheet leaves it off, has neither this file nor this row: `thread capabilities` takes both out, so it is not served at all rather than served and turned away."
|
|
21
38
|
|
|
22
|
-
export const
|
|
39
|
+
export const inboundAt = (webhook: string): string => `app/inbound/${webhook}/route.ts`
|
|
23
40
|
|
|
24
41
|
export const OPENAPI_AT = 'operations/_openapi.json'
|
|
25
42
|
|
|
@@ -34,9 +51,11 @@ export interface Capability {
|
|
|
34
51
|
|
|
35
52
|
readonly live: readonly Surface[]
|
|
36
53
|
|
|
37
|
-
readonly
|
|
54
|
+
readonly webhooks: readonly string[]
|
|
55
|
+
|
|
56
|
+
readonly signed: boolean
|
|
38
57
|
|
|
39
|
-
readonly
|
|
58
|
+
readonly browsable: boolean
|
|
40
59
|
|
|
41
60
|
readonly mcp: { readonly name: string; readonly description: string; readonly inputSchema: unknown }
|
|
42
61
|
readonly cli: { readonly invocation: string; readonly describes: string }
|