@reunionstudio/airlock-mcp 0.1.5 → 0.1.7
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/.agents/skills/airlock-mcp/SKILL.md +77 -0
- package/README.md +88 -0
- package/docs/install-surface.md +17 -0
- package/docs/workflows.md +85 -0
- package/package.json +3 -2
- package/setup.py +1 -1
- package/src/airlock_mcp/__init__.py +1 -1
- package/src/airlock_mcp/app_context.py +65 -0
- package/src/airlock_mcp/bootstrap.py +39 -0
- package/src/mcp.mjs +1 -1
- package/src/text.mjs +47 -3
|
@@ -194,6 +194,19 @@ Use three delivery modes:
|
|
|
194
194
|
- Co-development: develop the app and specs together, keeping the contract and
|
|
195
195
|
experience visible side by side.
|
|
196
196
|
|
|
197
|
+
Treat Airlock's built-in Streamlit Native App as a generic operating and
|
|
198
|
+
fallback surface. It is appropriate for administration, inspection, evidence,
|
|
199
|
+
workflow, and occasional manual action. It is not intended to become the best
|
|
200
|
+
domain application for every spec.
|
|
201
|
+
|
|
202
|
+
Recommend a purpose-built app when repeated, high-value work such as
|
|
203
|
+
reimbursement review, vendor onboarding, or employee-record changes benefits
|
|
204
|
+
from specialized summaries, calculations, terminology, evidence layout, or
|
|
205
|
+
controls. The app owns that experience while Airlock owns access, validation,
|
|
206
|
+
expectations, evidence, workflow, activity, and observable governance. Keep UI
|
|
207
|
+
layout and aggregation choices in app code unless they are genuinely governed
|
|
208
|
+
business semantics shared across interfaces.
|
|
209
|
+
|
|
197
210
|
Start by identifying:
|
|
198
211
|
|
|
199
212
|
1. The app goal: what the user needs to orient around or decide.
|
|
@@ -216,6 +229,29 @@ Airlock:
|
|
|
216
229
|
- `airlock.admin.*` performs administrative changes and operational mutations.
|
|
217
230
|
- `airlock.agent.*` performs governed user or agent work in the actor's scope.
|
|
218
231
|
|
|
232
|
+
Use `agent.list_my_work` as the actor's single operational inbox for workflow,
|
|
233
|
+
watcher, deadline, overdue, and exception work. Use `observe.work` for the
|
|
234
|
+
read-only account-wide current-work projection and `observe.activity` for event
|
|
235
|
+
history. Do not call the retired split work procedures.
|
|
236
|
+
|
|
237
|
+
For efficient watcher loops, call `agent.spec_state` first and cache the
|
|
238
|
+
role-scoped `STATE_TOKEN`. Retrieve `describe_spec`, file listings, or governed
|
|
239
|
+
data only after it changes. Poll `agent.list_my_work` independently because
|
|
240
|
+
deadlines and expectation windows can change without a spec mutation. For one selected logical file, compare
|
|
241
|
+
`agent.file_state(...).FILE_STATE_ID`; it rotates for data replacement,
|
|
242
|
+
workflow, attachment, and exact-reference changes. Use `observe.spec_state` and
|
|
243
|
+
`observe.file_state` only with observer/admin authority for account-wide state.
|
|
244
|
+
Do not substitute global observer tokens for an agent's scoped token.
|
|
245
|
+
|
|
246
|
+
Required source references are exact governed evidence, not filename fields.
|
|
247
|
+
When an active downstream-to-source link has `min_count > 0`, load the
|
|
248
|
+
downstream file into Draft, discover eligible sources with
|
|
249
|
+
`agent.list_eligible_source_files`, pin exact manifest rows with
|
|
250
|
+
`agent.add_file_reference`, and then call
|
|
251
|
+
`agent.edit_file_workflow(action => 'advance')`. Branch on
|
|
252
|
+
`SOURCE_REFERENCE_REQUIRED` and `SOURCE_REFERENCE_CHECK_FAILED`; do not bypass
|
|
253
|
+
the gate by copying an identifier into submitted business data.
|
|
254
|
+
|
|
219
255
|
For app-first work, prefer `observe.procedures`, `observe.specs`,
|
|
220
256
|
`observe.spec`, `observe.governance_map`, `observe.explain_access`,
|
|
221
257
|
`observe.health`, `observe.activity`, `observe.admin_activity`,
|
|
@@ -227,6 +263,36 @@ as `admin.list_specs`, `admin.describe_role`, `admin.get_spec`, or
|
|
|
227
263
|
Use `admin.*` only when the app is intentionally changing Airlock setup or
|
|
228
264
|
running an admin operation.
|
|
229
265
|
|
|
266
|
+
For a structural spec change with active files, treat
|
|
267
|
+
`SPEC_MIGRATION_REQUIRED` as a governed lifecycle, not an error to bypass. Use
|
|
268
|
+
`admin.create_spec_revision`, `admin.create_spec_migration`,
|
|
269
|
+
`admin.validate_spec_migration`, `admin.approve_spec_migration`,
|
|
270
|
+
`admin.activate_spec_migration`, bounded `admin.run_spec_migration` calls,
|
|
271
|
+
`observe.spec_migrations`, `observe.spec_migration`, and
|
|
272
|
+
`admin.retire_spec_migration`. Before activation, an abandoned `draft`,
|
|
273
|
+
`planned`, `validated`, or `approved` migration may be released with
|
|
274
|
+
`admin.cancel_spec_migration`; never describe cancellation as rollback after
|
|
275
|
+
activation. Preserve the full
|
|
276
|
+
proposed config, use only the bounded declarative transform over immutable
|
|
277
|
+
`column_id` values, and surface stable status, issue, progress, and lineage
|
|
278
|
+
fields. Never invent direct SQL/Python migration escape hatches.
|
|
279
|
+
|
|
280
|
+
If activation returns `SPEC_MIGRATION_ACTIVATED_WITH_REPAIR_REQUIRED`, the
|
|
281
|
+
target is already active. Repair the reported target view or materialized
|
|
282
|
+
table, call `admin.rebuild_access_index(TRUE)`, and re-read
|
|
283
|
+
`observe.spec_migration`; do not retry activation. Airlock intentionally keeps
|
|
284
|
+
stale surfaces unavailable and compiled agent access invalidated until repair.
|
|
285
|
+
|
|
286
|
+
The migration runner claims bounded work before stage or manifest effects.
|
|
287
|
+
Treat header renames as transformed successors, never zero-copy. For sequential
|
|
288
|
+
migrations, effective source currency comes from append-only valid
|
|
289
|
+
attestations. Re-attest an upgraded active file with unknown provenance by
|
|
290
|
+
loading its existing staged path; Airlock validates its exact digest and updates
|
|
291
|
+
the manifest in place. `source_preserved` keeps transformed source bytes out of
|
|
292
|
+
ordinary retention purge. `SPEC_MIGRATION_ACTIVE` blocks a second data-contract
|
|
293
|
+
revision until retirement but still permits metadata and governance repairs on
|
|
294
|
+
the current data version.
|
|
295
|
+
|
|
230
296
|
Restricted references are one-record interaction contracts for read-only
|
|
231
297
|
reference specs. If `agent.describe_spec`, `observe.spec`,
|
|
232
298
|
`observe.spec_config`, or `observe.reference_context` shows
|
|
@@ -246,6 +312,17 @@ For read-only planning and audit, use `observe.reference_context`,
|
|
|
246
312
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
247
313
|
without querying raw reference rows.
|
|
248
314
|
|
|
315
|
+
Attachments remain governed evidence. Agents should discover and manage them
|
|
316
|
+
through installed Airlock procedures, not by reading Airlock-owned stages or
|
|
317
|
+
generated storage directly. The Streamlit Native App can preview images and
|
|
318
|
+
text inline and can render bounded page-at-a-time PDF previews for files up to
|
|
319
|
+
100 MB and 2,000 pages. PDFs larger than 12 MB require an explicit open action;
|
|
320
|
+
the selected page and next two pages warm a private session cache. Full-file
|
|
321
|
+
download remains a short-lived Snowflake link when available. Successful PDF
|
|
322
|
+
page previews emit metadata-only `ATTACHMENT_PREVIEW` activity, never document
|
|
323
|
+
content or stage URLs. This UI preview capability does not grant MCP clients
|
|
324
|
+
direct attachment bytes.
|
|
325
|
+
|
|
249
326
|
Help the app follow the loop:
|
|
250
327
|
|
|
251
328
|
- Observe/read: fetch existing governed data through approved Airlock or
|
package/README.md
CHANGED
|
@@ -44,12 +44,63 @@ Current Airlock separates procedure intent:
|
|
|
44
44
|
specs, validating/loading data, workflow actions, attachments, delegations,
|
|
45
45
|
and references.
|
|
46
46
|
|
|
47
|
+
Use `airlock.agent.list_my_work(...)` for the current actor's unified workflow,
|
|
48
|
+
watcher, deadline, overdue, and exception inbox. Use `airlock.observe.work(...)`
|
|
49
|
+
for the read-only account-wide projection of current work, and
|
|
50
|
+
`airlock.observe.activity(...)` for historical events. The older split work
|
|
51
|
+
procedures are retired.
|
|
52
|
+
|
|
53
|
+
Watcher agents should poll `airlock.agent.spec_state(...)` before retrieving a
|
|
54
|
+
complete descriptor, file list, or governed dataset. Cache the
|
|
55
|
+
authorization-scoped `STATE_TOKEN` and perform the heavier read only when it
|
|
56
|
+
changes. Poll `airlock.agent.list_my_work(...)` independently because deadlines
|
|
57
|
+
and expectation windows can change with time without rotating a spec token.
|
|
58
|
+
After selecting a logical file, compare
|
|
59
|
+
`airlock.agent.file_state(...).FILE_STATE_ID`; that UUID rotates when its data,
|
|
60
|
+
workflow, attachments, or exact source references change. Observer clients use
|
|
61
|
+
the account-wide read-only `observe.spec_state(...)` and
|
|
62
|
+
`observe.file_state(...)` equivalents.
|
|
63
|
+
|
|
47
64
|
When building an app or workflow, prefer `observe.*` for read-only setup and
|
|
48
65
|
monitoring questions, `agent.*` for governed submissions in the actor's scope,
|
|
49
66
|
and `admin.*` only for intentional administrative mutation. Do not use retired
|
|
50
67
|
admin read wrappers such as `admin.list_specs`, `admin.describe_role`, or
|
|
51
68
|
`admin.list_events`; use the matching observe procedures instead.
|
|
52
69
|
|
|
70
|
+
Structural spec changes with active data use Airlock's governed migration
|
|
71
|
+
lifecycle. Agents should preserve the proposed config and guide an
|
|
72
|
+
administrator through immutable revision, declarative migration planning,
|
|
73
|
+
all-row proof, approval, activation, bounded execution, observable lineage, and
|
|
74
|
+
source retirement. `SPEC_MIGRATION_REQUIRED` is a safety boundary; it is not a
|
|
75
|
+
reason to mutate Airlock-owned storage directly.
|
|
76
|
+
|
|
77
|
+
Migration execution claims bounded work before storage effects. Renamed headers
|
|
78
|
+
produce transformed successors, sequential migrations rely on append-only
|
|
79
|
+
validation attestations, and upgraded files with unknown provenance are
|
|
80
|
+
re-attested in place through normal `load_data`. `source_preserved` protects
|
|
81
|
+
transformed source bytes from ordinary retention purge, while
|
|
82
|
+
`SPEC_MIGRATION_ACTIVE` prevents another data-contract revision until the
|
|
83
|
+
current migration retires.
|
|
84
|
+
|
|
85
|
+
## Built-In UI And Purpose-Built Apps
|
|
86
|
+
|
|
87
|
+
Airlock's Streamlit Native App is deliberately a generic operating and fallback
|
|
88
|
+
surface. It supports administration, inspection, governed data and attachment
|
|
89
|
+
review, workflow visibility, and safe manual action. It should not be treated as
|
|
90
|
+
a universal domain application builder.
|
|
91
|
+
|
|
92
|
+
Repeated, high-value decisions such as reimbursements, vendor onboarding, or
|
|
93
|
+
employee-record changes may deserve purpose-built interfaces. Airlock MCP should
|
|
94
|
+
recommend app-first or co-development for those cases and help build the custom
|
|
95
|
+
surface against Airlock contracts. The app owns domain summaries,
|
|
96
|
+
calculations, terminology, and interaction design; Airlock continues to own
|
|
97
|
+
access, validation, expectations, evidence, workflow, activity, and observable
|
|
98
|
+
governance.
|
|
99
|
+
|
|
100
|
+
Do not add UI layout or aggregation fields to a spec merely to make the generic
|
|
101
|
+
Native App imitate custom software. Presentation belongs in app code unless it
|
|
102
|
+
is genuinely governed business semantics shared across interfaces.
|
|
103
|
+
|
|
53
104
|
## Install
|
|
54
105
|
|
|
55
106
|
Dogfood directly from GitHub:
|
|
@@ -221,6 +272,31 @@ For app-first work against installed Airlock, start with `observe.procedures`,
|
|
|
221
272
|
before designing direct SQL helpers. These payloads are intended to be useful
|
|
222
273
|
to agents as well as humans.
|
|
223
274
|
|
|
275
|
+
For operational queues, call `agent.list_my_work` in the actor's scope. An
|
|
276
|
+
observer may call `observe.work` for all current work; historical questions
|
|
277
|
+
belong to `observe.activity`.
|
|
278
|
+
|
|
279
|
+
Required source references are a governed submission contract. When a
|
|
280
|
+
downstream spec has an active source link with `min_count > 0`, load the file
|
|
281
|
+
into Draft, discover eligible evidence with `agent.list_eligible_source_files`,
|
|
282
|
+
pin exact manifest rows with `agent.add_file_reference`, and only then call
|
|
283
|
+
`agent.edit_file_workflow(action => 'advance')`. Missing, removed, or
|
|
284
|
+
wrong-workflow-state evidence returns `SOURCE_REFERENCE_REQUIRED` without
|
|
285
|
+
moving the file. Do not replace the exact Airlock reference with a filename or
|
|
286
|
+
identifier copied into business data.
|
|
287
|
+
|
|
288
|
+
Structural spec changes with active files use Airlock's governed two-version
|
|
289
|
+
migration lifecycle. Treat `SPEC_MIGRATION_REQUIRED` as a request to create an
|
|
290
|
+
immutable revision and migration, validate and approve it, activate the target,
|
|
291
|
+
drain bounded batches with `admin.run_spec_migration`, inspect progress and
|
|
292
|
+
lineage through `observe.spec_migration`, and retire the source only after the
|
|
293
|
+
evidence gate passes. Use `observe.spec_migrations` to discover and filter
|
|
294
|
+
migrations. Before activation, an abandoned `draft`, `planned`, `validated`, or
|
|
295
|
+
`approved` migration may be released with `admin.cancel_spec_migration`;
|
|
296
|
+
cancellation is not rollback after activation. The transform language is intentionally limited to
|
|
297
|
+
mechanical mappings, defaults, and safe casts; semantic transforms belong in a
|
|
298
|
+
purpose-built process that reloads through normal Airlock validation.
|
|
299
|
+
|
|
224
300
|
Restricted references are one-record interaction contracts. When
|
|
225
301
|
`observe.reference_context`, `observe.spec_config`, or `agent.describe_spec`
|
|
226
302
|
shows `restricted_reference` or `reference_config.restricted_reference`, agents
|
|
@@ -240,6 +316,18 @@ inspect `observe.usage_limits`, `observe.usage_limit`, and
|
|
|
240
316
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
241
317
|
without reading raw reference rows.
|
|
242
318
|
|
|
319
|
+
Airlock's Streamlit Native App can inspect governed attachment evidence without
|
|
320
|
+
moving it into a separate document service. Images and text preview inline.
|
|
321
|
+
PDFs up to 100 MB and 2,000 pages render one selected page at a time; the
|
|
322
|
+
selected page and next two pages are loaded as one bounded window so ordinary
|
|
323
|
+
forward navigation can use the session cache. PDFs larger than 12 MB require an
|
|
324
|
+
explicit open action. Rendering is bounded by time, dimensions, concurrency,
|
|
325
|
+
output size, session storage, and expiry, while full-file access remains a
|
|
326
|
+
short-lived Snowflake download when available. Successful PDF page previews
|
|
327
|
+
emit metadata-only `ATTACHMENT_PREVIEW` activity. This human-facing capability
|
|
328
|
+
does not permit an MCP agent to bypass attachment procedures or read underlying
|
|
329
|
+
stage objects directly.
|
|
330
|
+
|
|
243
331
|
For governed Markdown knowledge, use the `okf-knowledge-bundle` pattern. It
|
|
244
332
|
sets `core_config.payload_adapter` to `okf_knowledge_bundle` so installed
|
|
245
333
|
Airlock can load locally validated bundles through
|
package/docs/install-surface.md
CHANGED
|
@@ -38,6 +38,23 @@ known lookup value and purpose, with `observe.reference_context`,
|
|
|
38
38
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
39
39
|
for planning and audit.
|
|
40
40
|
|
|
41
|
+
The installed Streamlit Native App also provides governed attachment
|
|
42
|
+
inspection: inline image/text previews and bounded, page-at-a-time PDF preview
|
|
43
|
+
for documents up to 100 MB and 2,000 pages. The selected PDF page warms the next
|
|
44
|
+
two pages in the session cache; large PDFs require explicit open, and full-file
|
|
45
|
+
access uses Snowflake download links when available. Successful PDF page
|
|
46
|
+
previews emit metadata-only `ATTACHMENT_PREVIEW` activity. This UI capability
|
|
47
|
+
does not grant MCP clients direct stage access.
|
|
48
|
+
|
|
49
|
+
The Native App is deliberately a generic operating and fallback surface. It
|
|
50
|
+
should support administration, inspection, evidence, workflow, and safe manual
|
|
51
|
+
action without accumulating every domain's presentation rules. Airlock MCP
|
|
52
|
+
should recommend app-first or co-development when repeated, high-value work
|
|
53
|
+
deserves a purpose-built interface. The custom app owns domain summaries,
|
|
54
|
+
calculations, terminology, and controls while Airlock remains the governed
|
|
55
|
+
backend. UI layout and aggregation hints should not be added to specs merely to
|
|
56
|
+
polish the generic app.
|
|
57
|
+
|
|
41
58
|
The connector package and MCP server live in `reunionstudio/airlock-mcp`.
|
|
42
59
|
This workbench provides the spec-building implementation inside that one
|
|
43
60
|
installed Airlock MCP experience.
|
package/docs/workflows.md
CHANGED
|
@@ -154,6 +154,17 @@ unless the user asks to change specs. Start by asking for:
|
|
|
154
154
|
- the available Airlock/Snowflake access path
|
|
155
155
|
- identity, evidence, timestamp, approval, and separation-of-duties needs
|
|
156
156
|
|
|
157
|
+
Airlock's built-in Streamlit Native App is a generic operating and fallback
|
|
158
|
+
surface, not a universal domain application builder. Use it for administration,
|
|
159
|
+
inspection, governed evidence, workflow, and occasional manual action. For
|
|
160
|
+
repeated high-value decisions, prefer a purpose-built app when domain-specific
|
|
161
|
+
summaries, calculations, evidence layout, terminology, or controls materially
|
|
162
|
+
improve the work.
|
|
163
|
+
|
|
164
|
+
Keep those presentation choices in app code. Do not add layout or aggregation
|
|
165
|
+
fields to an Airlock spec merely to make the generic UI imitate custom
|
|
166
|
+
software. Airlock remains the governed backend for either surface.
|
|
167
|
+
|
|
157
168
|
Use the installed Airlock procedure grammar:
|
|
158
169
|
|
|
159
170
|
- `airlock.observe.*` is read-only and should answer discovery, governance,
|
|
@@ -163,6 +174,69 @@ Use the installed Airlock procedure grammar:
|
|
|
163
174
|
delegations.
|
|
164
175
|
- `airlock.admin.*` is for administrative mutation and operational changes.
|
|
165
176
|
|
|
177
|
+
For work discovery, use `agent.list_my_work` as the current actor's unified
|
|
178
|
+
inbox. Observers use `observe.work` for account-wide current work and
|
|
179
|
+
`observe.activity` for historical events. Do not recreate separate workflow
|
|
180
|
+
and expectation inbox calls in app code.
|
|
181
|
+
|
|
182
|
+
Watcher loops should call `agent.spec_state` before larger reads. Cache its
|
|
183
|
+
authorization-scoped `STATE_TOKEN` and retrieve descriptors, file lists, or
|
|
184
|
+
governed data only when it changes. Poll `agent.list_my_work` independently
|
|
185
|
+
because deadlines and expectation windows can change without rotating the spec
|
|
186
|
+
token. Once the app tracks one logical file,
|
|
187
|
+
compare `agent.file_state(...).FILE_STATE_ID` to detect data replacement,
|
|
188
|
+
workflow movement, attachment changes, or exact-reference changes. Observer
|
|
189
|
+
services may use the global read-only `observe.spec_state` and
|
|
190
|
+
`observe.file_state` equivalents.
|
|
191
|
+
|
|
192
|
+
For downstream work that requires governed source evidence, use the installed
|
|
193
|
+
source-reference sequence: load the downstream Draft, call
|
|
194
|
+
`agent.list_eligible_source_files`, pin exact source manifest rows with
|
|
195
|
+
`agent.add_file_reference`, then advance workflow. Active source links with
|
|
196
|
+
`min_count > 0` are enforced by `agent.edit_file_workflow`; required sources
|
|
197
|
+
must still exist, remain unremoved, and match any configured
|
|
198
|
+
`required_workflow_status`. Branch on `SOURCE_REFERENCE_REQUIRED` or
|
|
199
|
+
`SOURCE_REFERENCE_CHECK_FAILED` and show the returned `ISSUES` instead of
|
|
200
|
+
guessing at alternate source identifiers.
|
|
201
|
+
|
|
202
|
+
When an app or administrator changes a spec's data contract, do not work around
|
|
203
|
+
`SPEC_MIGRATION_REQUIRED` with direct table, stage, or view changes. Use the
|
|
204
|
+
installed governed lifecycle: `admin.create_spec_revision`,
|
|
205
|
+
`admin.create_spec_migration`, `admin.validate_spec_migration`,
|
|
206
|
+
`admin.approve_spec_migration`, `admin.activate_spec_migration`, bounded calls
|
|
207
|
+
to `admin.run_spec_migration`, inspection through
|
|
208
|
+
`observe.spec_migrations` and `observe.spec_migration`, and finally
|
|
209
|
+
`admin.retire_spec_migration`. Before activation, use
|
|
210
|
+
`admin.cancel_spec_migration` to release an abandoned `draft`, `planned`,
|
|
211
|
+
`validated`, or `approved` migration. Cancellation is not rollback after
|
|
212
|
+
activation. The
|
|
213
|
+
transform is declarative and keyed by immutable `column_id` values; arbitrary
|
|
214
|
+
SQL or Python is not part of the contract. Approval is intent, activation is
|
|
215
|
+
the write-version switch, and retirement is a separate guarded action.
|
|
216
|
+
|
|
217
|
+
Treat `SPEC_MIGRATION_ACTIVATED_WITH_REPAIR_REQUIRED` as a committed activation,
|
|
218
|
+
not a retryable pre-activation failure. Follow the returned issues to rebuild
|
|
219
|
+
the target view or materialized table, then call
|
|
220
|
+
`admin.rebuild_access_index(TRUE)` and re-read `observe.spec_migration`. Airlock
|
|
221
|
+
keeps stale read surfaces unavailable and compiled agent access invalidated
|
|
222
|
+
until repair succeeds.
|
|
223
|
+
|
|
224
|
+
`admin.run_spec_migration` claims each bounded item batch before stage or
|
|
225
|
+
manifest side effects. A header rename always creates a transformed successor;
|
|
226
|
+
zero-copy is reserved for stored headers and values that already satisfy the
|
|
227
|
+
target contract. Use append-only valid attestations, not only the manifest's
|
|
228
|
+
original version pointer, when a file moves through sequential migrations.
|
|
229
|
+
|
|
230
|
+
An upgraded active file may have `validation_provenance_status = 'unknown'`.
|
|
231
|
+
Re-load its existing staged path through `load_data`: after validation and an
|
|
232
|
+
exact digest recheck, Airlock re-attests the existing manifest in place instead
|
|
233
|
+
of creating a duplicate stage-path owner. A `source_preserved` migration keeps
|
|
234
|
+
transformed source bytes outside ordinary retention purge; `forward_only`
|
|
235
|
+
allows normal retention. While a migration is active,
|
|
236
|
+
`SPEC_MIGRATION_ACTIVE` blocks another data-contract revision until retirement,
|
|
237
|
+
although metadata, access, policy, expectation, and workflow repairs remain
|
|
238
|
+
allowed on the current data version.
|
|
239
|
+
|
|
166
240
|
For app-first work, start with observe payloads such as `observe.procedures`,
|
|
167
241
|
`observe.specs`, `observe.spec`, `observe.governance_map`,
|
|
168
242
|
`observe.explain_access`, `observe.health`, `observe.activity`,
|
|
@@ -187,6 +261,17 @@ budgeting. Use `observe.reference_context`, `observe.usage_limits`,
|
|
|
187
261
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
188
262
|
for planning and audit without reading raw reference rows.
|
|
189
263
|
|
|
264
|
+
## Governed Attachment Preview
|
|
265
|
+
|
|
266
|
+
Attachments remain governed evidence. Agents should discover and manage them
|
|
267
|
+
through installed Airlock procedures rather than reading Airlock-owned stages.
|
|
268
|
+
In the Streamlit Native App, images and text can preview inline, and PDFs up to
|
|
269
|
+
100 MB and 2,000 pages can render one selected page at a time. Airlock renders a
|
|
270
|
+
bounded three-page window so the next two pages are normally session-cache
|
|
271
|
+
hits; PDFs larger than 12 MB require an explicit open action. Full-file download
|
|
272
|
+
remains available through a short-lived Snowflake link when the runtime can
|
|
273
|
+
create one. Preview activity emits metadata-only `ATTACHMENT_PREVIEW` events.
|
|
274
|
+
|
|
190
275
|
The app should follow the loop:
|
|
191
276
|
|
|
192
277
|
1. Observe/read governed records through approved Airlock or Snowflake surfaces.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reunionstudio/airlock-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Single-install MCP interface for Airlock agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"bin",
|
|
29
29
|
"docs",
|
|
30
|
-
"src",
|
|
30
|
+
"src/*.mjs",
|
|
31
|
+
"src/airlock_mcp/*.py",
|
|
31
32
|
".agents",
|
|
32
33
|
"patterns",
|
|
33
34
|
"schemas",
|
package/setup.py
CHANGED
|
@@ -20,6 +20,12 @@ The canonical specs live in the specs repo or installed Airlock. Files here are
|
|
|
20
20
|
snapshots, samples, generated helpers, and planning context for app development.
|
|
21
21
|
Refresh them when the canonical spec changes.
|
|
22
22
|
|
|
23
|
+
Airlock's built-in Streamlit Native App is a generic operating and fallback
|
|
24
|
+
surface. A purpose-built app is the preferred place for domain-specific
|
|
25
|
+
summaries, calculations, evidence layout, terminology, and controls when those
|
|
26
|
+
features materially improve repeated, high-value work. Keep presentation in
|
|
27
|
+
app code rather than adding UI layout or aggregation hints to Airlock specs.
|
|
28
|
+
|
|
23
29
|
Use:
|
|
24
30
|
|
|
25
31
|
- `specs.manifest.json` to track which specs the app reads from or writes to.
|
|
@@ -36,6 +42,28 @@ Installed Airlock separates procedure intent:
|
|
|
36
42
|
- `agent.*`: governed agent work in the actor's scope.
|
|
37
43
|
- `admin.*`: administrative mutation and operational changes.
|
|
38
44
|
|
|
45
|
+
Use `agent.list_my_work` for the actor's unified current-work inbox,
|
|
46
|
+
`observe.work` for account-wide current work, and `observe.activity` for
|
|
47
|
+
historical events. The older split workflow/expectation work calls are retired.
|
|
48
|
+
|
|
49
|
+
Required source references are exact governed evidence. For an active source
|
|
50
|
+
link with `min_count > 0`, load the downstream Draft, discover eligible files
|
|
51
|
+
with `agent.list_eligible_source_files`, pin exact manifest rows with
|
|
52
|
+
`agent.add_file_reference`, and then advance workflow. Missing or invalid
|
|
53
|
+
evidence returns `SOURCE_REFERENCE_REQUIRED` without moving the file.
|
|
54
|
+
|
|
55
|
+
Structural spec changes with active files use a governed two-version migration
|
|
56
|
+
lifecycle. Treat `SPEC_MIGRATION_REQUIRED` as a request to create an immutable
|
|
57
|
+
revision and migration, validate and approve it, activate the target, run
|
|
58
|
+
bounded migration batches, list work with `observe.spec_migrations`, inspect
|
|
59
|
+
evidence with `observe.spec_migration`, and retire the source only after Airlock
|
|
60
|
+
reports that it is drained. Before activation, an abandoned `draft`, `planned`,
|
|
61
|
+
`validated`, or `approved` migration may be cancelled with
|
|
62
|
+
`admin.cancel_spec_migration`; cancellation is not rollback. Use only the
|
|
63
|
+
declarative mechanical transform keyed by immutable `column_id`; semantic
|
|
64
|
+
transforms belong in a purpose-built process that reloads through normal
|
|
65
|
+
Airlock validation.
|
|
66
|
+
|
|
39
67
|
Prefer `observe.*` for app read-side setup and monitoring questions. Use
|
|
40
68
|
`observe.admin_activity` for broad admin mutation and maintenance audit
|
|
41
69
|
questions, and `observe.spec_admin_activity` for one spec's definition-change
|
|
@@ -54,6 +82,14 @@ purpose, and role lens. Use `observe.reference_context`,
|
|
|
54
82
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
55
83
|
for planning and audit without reading raw reference rows.
|
|
56
84
|
|
|
85
|
+
Attachments remain governed evidence. Agents should discover and manage them
|
|
86
|
+
through installed Airlock procedures, not by reading Airlock-owned stages.
|
|
87
|
+
The Streamlit Native App can preview images and text inline and can render
|
|
88
|
+
bounded page-at-a-time PDF previews for files up to 100 MB and 2,000 pages.
|
|
89
|
+
PDFs larger than 12 MB require explicit open; successful page previews emit
|
|
90
|
+
metadata-only `ATTACHMENT_PREVIEW` activity and do not grant MCP clients direct
|
|
91
|
+
attachment bytes.
|
|
92
|
+
|
|
57
93
|
Do not store credentials here. Do not write directly to Airlock-owned tables,
|
|
58
94
|
stages, generated views, or generated tables. Use approved Airlock/Snowflake
|
|
59
95
|
access paths and submit governed decisions or actions through spec contracts.
|
|
@@ -64,6 +100,13 @@ APP_AGENTS = """# Airlock App Guidance
|
|
|
64
100
|
|
|
65
101
|
This repo may contain application code that uses Airlock specs.
|
|
66
102
|
|
|
103
|
+
Treat the built-in Streamlit Native App as a generic operating and fallback
|
|
104
|
+
surface. Build a purpose-built interface when domain-specific presentation
|
|
105
|
+
materially improves repeated, high-value work. The custom app owns the
|
|
106
|
+
experience; Airlock remains the governed backend for access, validation,
|
|
107
|
+
expectations, evidence, workflow, activity, and observability. Do not add UI
|
|
108
|
+
layout or aggregation fields to specs solely for the built-in app.
|
|
109
|
+
|
|
67
110
|
## Modes
|
|
68
111
|
|
|
69
112
|
- Spec-first: design governed specs before building the app surface.
|
|
@@ -96,12 +139,29 @@ Installed Airlock procedure grammar:
|
|
|
96
139
|
- `admin.*` is administrative mutation. Do not use retired admin read wrappers;
|
|
97
140
|
use observe list/detail procedures instead.
|
|
98
141
|
|
|
142
|
+
Use `agent.list_my_work` for the current actor's unified work inbox. Use
|
|
143
|
+
`observe.work` for account-wide current work and `observe.activity` for event
|
|
144
|
+
history.
|
|
145
|
+
|
|
146
|
+
For structural spec changes with active files, treat
|
|
147
|
+
`SPEC_MIGRATION_REQUIRED` as the start of Airlock's governed two-version
|
|
148
|
+
lifecycle. Use immutable revisions, bounded `admin.run_spec_migration` calls,
|
|
149
|
+
`observe.spec_migrations` discovery, `observe.spec_migration` evidence, and
|
|
150
|
+
guarded source retirement. Before activation, `admin.cancel_spec_migration` may
|
|
151
|
+
release an abandoned migration; it is not a post-activation rollback. Do not bypass
|
|
152
|
+
the lifecycle with direct stage, table, or view changes.
|
|
153
|
+
|
|
99
154
|
For restricted reference specs, do not enumerate protected object paths or use
|
|
100
155
|
broad `agent.select_reference_data`. Use `agent.get_reference_record` for a
|
|
101
156
|
known lookup value and purpose, and use `observe.reference_context`,
|
|
102
157
|
`observe.usage_limits`, `observe.usage_limit`, and
|
|
103
158
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
104
159
|
for planning and audit.
|
|
160
|
+
|
|
161
|
+
For attachments, use installed Airlock procedures and governed UI surfaces.
|
|
162
|
+
The Streamlit Native App can preview images/text and bounded PDF pages, but
|
|
163
|
+
`ATTACHMENT_PREVIEW` activity is metadata-only and MCP clients must not read
|
|
164
|
+
Airlock-owned stages directly.
|
|
105
165
|
"""
|
|
106
166
|
|
|
107
167
|
|
|
@@ -160,8 +220,13 @@ def _manifest(mode: str, entries: list[dict[str, Any]]) -> dict[str, Any]:
|
|
|
160
220
|
"installed_airlock_contract": {
|
|
161
221
|
"observe": "read-only governance observation, context, activity, health, billing events, and access explanation",
|
|
162
222
|
"agent": "governed agent work in the actor scope",
|
|
223
|
+
"work": "agent.list_my_work is the actor inbox; observe.work is account-wide current work; observe.activity is history",
|
|
224
|
+
"required_source_references": "load Draft, list eligible sources, pin exact manifest rows, then advance; SOURCE_REFERENCE_REQUIRED blocks missing evidence",
|
|
225
|
+
"spec_migration": "immutable two-version lifecycle; list with observe.spec_migrations, run bounded admin migration batches, inspect observe.spec_migration evidence, cancel only before activation, and retire only after the source is drained",
|
|
163
226
|
"admin": "administrative mutation and operational changes",
|
|
164
227
|
"restricted_reference": "one-record reference lookup through agent.get_reference_record; do not enumerate protected reference paths",
|
|
228
|
+
"attachment_preview": "governed Streamlit preview emits metadata-only ATTACHMENT_PREVIEW; MCP clients do not get direct stage access",
|
|
229
|
+
"application_surface": "built-in Streamlit is a generic operating/fallback surface; purpose-built apps own domain UI and use Airlock as the governed backend",
|
|
165
230
|
},
|
|
166
231
|
"specs": entries,
|
|
167
232
|
"tracks": {
|
|
@@ -99,6 +99,14 @@ Airlock context. It creates `airlock/specs.manifest.json`,
|
|
|
99
99
|
folders. These files are app-local references, not canonical specs. Canonical
|
|
100
100
|
specs live in the specs repo or installed Airlock.
|
|
101
101
|
|
|
102
|
+
Treat Airlock's built-in Streamlit Native App as a generic operating and
|
|
103
|
+
fallback surface. It supports administration, inspection, evidence, workflow,
|
|
104
|
+
and safe manual action; it is not a universal domain application builder.
|
|
105
|
+
Recommend a purpose-built app when repeated, high-value work benefits from
|
|
106
|
+
domain-specific summaries, calculations, evidence layout, terminology, or
|
|
107
|
+
controls. Keep those presentation choices in app code. Do not add UI layout or
|
|
108
|
+
aggregation fields to a spec merely to improve the generic app.
|
|
109
|
+
|
|
102
110
|
Identify:
|
|
103
111
|
|
|
104
112
|
- the app goal and decision the app should support
|
|
@@ -118,6 +126,28 @@ Installed Airlock separates procedure intent:
|
|
|
118
126
|
- `agent.*`: governed agent work in the actor's scope.
|
|
119
127
|
- `admin.*`: administrative mutation and operational changes.
|
|
120
128
|
|
|
129
|
+
Use `agent.list_my_work` for the actor's unified current-work inbox,
|
|
130
|
+
`observe.work` for account-wide current work, and `observe.activity` for
|
|
131
|
+
historical events. The older split workflow/expectation work calls are retired.
|
|
132
|
+
|
|
133
|
+
For active source links with `min_count > 0`, load the downstream file into
|
|
134
|
+
Draft, discover eligible evidence with `agent.list_eligible_source_files`, pin
|
|
135
|
+
exact manifest rows with `agent.add_file_reference`, and then advance workflow.
|
|
136
|
+
Missing, removed, or wrong-state evidence returns `SOURCE_REFERENCE_REQUIRED`
|
|
137
|
+
without moving the file.
|
|
138
|
+
|
|
139
|
+
For a structural spec change with active files, treat
|
|
140
|
+
`SPEC_MIGRATION_REQUIRED` as a governed two-version lifecycle. Create the
|
|
141
|
+
immutable revision and migration, validate and approve it, activate the target,
|
|
142
|
+
run bounded `admin.run_spec_migration` batches, inspect progress and lineage
|
|
143
|
+
with `observe.spec_migration`, and retire the source only after it is drained.
|
|
144
|
+
Use `observe.spec_migrations` to discover lifecycle work. Before activation,
|
|
145
|
+
`admin.cancel_spec_migration` may release an abandoned `draft`, `planned`,
|
|
146
|
+
`validated`, or `approved` migration; it is not rollback after activation. Use
|
|
147
|
+
the bounded declarative transform for mechanical changes; semantic
|
|
148
|
+
transforms belong in a purpose-built process that reloads through normal
|
|
149
|
+
Airlock validation.
|
|
150
|
+
|
|
121
151
|
For app-first work, use observe payloads such as `observe.procedures`,
|
|
122
152
|
`observe.specs`, `observe.spec`, `observe.governance_map`,
|
|
123
153
|
`observe.explain_access`, `observe.health`, `observe.activity`,
|
|
@@ -139,6 +169,15 @@ value, purpose, and role lens. Use `observe.usage_limits`,
|
|
|
139
169
|
`observe.explain_access(action => 'get_reference_record', object_key => ...)`
|
|
140
170
|
for planning and audit without reading raw reference rows.
|
|
141
171
|
|
|
172
|
+
Attachments remain governed evidence. Agents should discover and manage them
|
|
173
|
+
through installed Airlock procedures, not by reading Airlock-owned stages
|
|
174
|
+
directly. The Streamlit Native App can preview images and text inline and can
|
|
175
|
+
render bounded page-at-a-time PDF previews for files up to 100 MB and 2,000
|
|
176
|
+
pages. PDFs larger than 12 MB require an explicit open action; the selected
|
|
177
|
+
page and next two pages warm a private session cache. Successful PDF page
|
|
178
|
+
previews emit metadata-only `ATTACHMENT_PREVIEW` activity and do not grant MCP
|
|
179
|
+
clients direct attachment bytes.
|
|
180
|
+
|
|
142
181
|
The app may orient the user with summaries, comparisons, rankings, exception
|
|
143
182
|
queues, proposals, or dashboards. It should submit governed choices back
|
|
144
183
|
through an Airlock spec contract. Do not write directly to Airlock-owned tables,
|
package/src/mcp.mjs
CHANGED
|
@@ -44,7 +44,7 @@ export function handleMcpRequest(message) {
|
|
|
44
44
|
},
|
|
45
45
|
serverInfo: {
|
|
46
46
|
name: "airlock",
|
|
47
|
-
version: "0.1.
|
|
47
|
+
version: "0.1.7",
|
|
48
48
|
},
|
|
49
49
|
instructions:
|
|
50
50
|
"Airlock MCP helps agents improve processes with Airlock specs and build apps or workflows that use existing specs. Use airlock_start for orientation or the airlock_* tools to bootstrap, draft, check, summarize, export, and render specs.",
|
package/src/text.mjs
CHANGED
|
@@ -62,9 +62,29 @@ administrative mutation. Prefer observe payloads such as
|
|
|
62
62
|
\`observe.activity\`, \`observe.admin_activity\`, \`observe.spec_admin_activity\`,
|
|
63
63
|
and \`observe.billing_events\` before inventing custom read paths. For \`alter_spec\`
|
|
64
64
|
activity, use \`CHANGED_SECTIONS\` and \`CHANGED_FIELDS\` to triage what changed
|
|
65
|
-
before fetching version snapshots.
|
|
65
|
+
before fetching version snapshots. For watcher loops, cache the role-scoped
|
|
66
|
+
\`agent.spec_state(...).STATE_TOKEN\` and do larger reads only when it changes.
|
|
67
|
+
After selecting one logical file, compare
|
|
68
|
+
\`agent.file_state(...).FILE_STATE_ID\` to detect data, workflow, attachment,
|
|
69
|
+
or exact-reference changes. Observer services may use the account-wide
|
|
70
|
+
\`observe.spec_state\` and \`observe.file_state\` equivalents. Offer to run \`airlock-mcp init-app-context\`
|
|
66
71
|
in the app repo to seed \`airlock/specs.manifest.json\`, spec snapshots, sample records, and
|
|
67
72
|
generated helper folders. Help code the app using approved Airlock/Snowflake access paths.
|
|
73
|
+
Treat Airlock's built-in Streamlit app as a generic operating and fallback
|
|
74
|
+
surface, not a universal domain app. When a repeated, high-value decision needs
|
|
75
|
+
domain-specific summaries, calculations, evidence layout, terminology, or
|
|
76
|
+
controls, recommend a purpose-built app and use Airlock as its governed backend.
|
|
77
|
+
Keep those presentation choices in app code; do not add layout or aggregation
|
|
78
|
+
fields to a spec merely to improve the generic UI.
|
|
79
|
+
When a structural spec change with active files returns
|
|
80
|
+
\`SPEC_MIGRATION_REQUIRED\`, use Airlock's governed two-version lifecycle:
|
|
81
|
+
create the immutable revision and migration, validate and approve it, activate
|
|
82
|
+
the target, drain bounded \`admin.run_spec_migration\` batches, inspect
|
|
83
|
+
\`observe.spec_migrations\` and \`observe.spec_migration\`, and retire the source
|
|
84
|
+
only after it is drained. Before activation, an abandoned migration may use
|
|
85
|
+
\`admin.cancel_spec_migration\`; cancellation is not post-activation rollback.
|
|
86
|
+
Use the declarative mechanical transform; semantic transforms belong in a
|
|
87
|
+
purpose-built process that reloads through normal Airlock validation.
|
|
68
88
|
When a reference spec declares \`restricted_reference\` or
|
|
69
89
|
\`reference_config.restricted_reference\`, do not enumerate values, build a
|
|
70
90
|
populated picker, or call broad \`agent.select_reference_data\`. Get the lookup
|
|
@@ -79,6 +99,12 @@ role lens. It returns at most one record, applies reference row filters, checks
|
|
|
79
99
|
\`observe.reference_context\`, \`observe.usage_limits\`, \`observe.usage_limit\`,
|
|
80
100
|
and \`observe.explain_access(action => 'get_reference_record', object_key => ...)\`
|
|
81
101
|
for read-only planning and audit.
|
|
102
|
+
Attachments remain governed evidence. Agents should discover and manage them
|
|
103
|
+
through installed Airlock procedures, not by reading Airlock-owned stages.
|
|
104
|
+
The Streamlit Native App can preview images/text and bounded page-at-a-time
|
|
105
|
+
PDFs up to 100 MB and 2,000 pages; PDFs larger than 12 MB require explicit
|
|
106
|
+
open. Successful page previews emit metadata-only \`ATTACHMENT_PREVIEW\`
|
|
107
|
+
activity and do not grant MCP clients direct attachment bytes.
|
|
82
108
|
|
|
83
109
|
Do not use retired admin read wrappers such as
|
|
84
110
|
\`admin.list_specs\`, \`admin.describe_role\`, or \`admin.list_events\`; use
|
|
@@ -105,6 +131,7 @@ Airlock MCP will offer:
|
|
|
105
131
|
- spec design with the bundled workbench
|
|
106
132
|
- Airlock operating patterns for OODA loops and separation of duties
|
|
107
133
|
- read-only observe procedures for governance maps, health, access explanation, activity, billing events, and context packets
|
|
134
|
+
- scoped spec and file state tokens for efficient watcher polling
|
|
108
135
|
- app context seeding with spec snapshots and manifests
|
|
109
136
|
- app and workflow coding against existing Airlock specs
|
|
110
137
|
- observe specs for controlled interface ingestion
|
|
@@ -198,16 +225,33 @@ read-side discovery with observe payloads such as \`observe.procedures\`,
|
|
|
198
225
|
\`observe.explain_access\`, \`observe.health\`, \`observe.activity\`,
|
|
199
226
|
\`observe.admin_activity\`, \`observe.spec_admin_activity\`, and \`observe.billing_events\`;
|
|
200
227
|
for \`alter_spec\` activity, use \`CHANGED_SECTIONS\` and \`CHANGED_FIELDS\` to
|
|
201
|
-
triage what changed before fetching version snapshots.
|
|
228
|
+
triage what changed before fetching version snapshots. For watcher loops, poll
|
|
229
|
+
\`agent.spec_state\` and compare its scoped \`STATE_TOKEN\` before larger reads;
|
|
230
|
+
compare \`agent.file_state(...).FILE_STATE_ID\` for one selected file. Observer
|
|
231
|
+
services use \`observe.spec_state\` and \`observe.file_state\` for account-wide
|
|
232
|
+
read-only state. Do not use retired admin
|
|
202
233
|
read wrappers such as \`admin.list_specs\`, \`admin.describe_role\`, or
|
|
203
234
|
\`admin.list_events\`. If a reference spec declares \`restricted_reference\` or
|
|
204
235
|
\`reference_config.restricted_reference\`, do not enumerate the protected
|
|
205
236
|
reference; use \`agent.get_reference_record\` for a known lookup value and
|
|
206
237
|
\`observe.usage_limits\` / \`observe.usage_limit\` for budget visibility. It can
|
|
238
|
+
also explain governed attachment preview: Streamlit can preview images/text and
|
|
239
|
+
bounded PDF pages, while \`ATTACHMENT_PREVIEW\` remains metadata-only and agents
|
|
240
|
+
must use Airlock procedures instead of direct stage reads. Airlock MCP can
|
|
207
241
|
seed an app repo with \`airlock/specs.manifest.json\`, spec snapshots, sample
|
|
208
242
|
records, and generated helper folders. The app should submit decisions,
|
|
209
243
|
approvals, actions, comments, or follow-ups through Airlock spec contracts, not
|
|
210
|
-
direct table writes.
|
|
244
|
+
direct table writes. Treat the built-in Streamlit app as a generic
|
|
245
|
+
operating/fallback surface. Recommend a purpose-built app when recurring,
|
|
246
|
+
high-value domain work benefits from specialized summaries, calculations,
|
|
247
|
+
evidence presentation, terminology, or controls. Keep those choices in app code
|
|
248
|
+
rather than adding UI layout or aggregation hints to Airlock specs. For a
|
|
249
|
+
structural spec change with active files, treat \`SPEC_MIGRATION_REQUIRED\` as
|
|
250
|
+
the governed two-version lifecycle: use immutable revisions, bounded
|
|
251
|
+
\`admin.run_spec_migration\` calls, \`observe.spec_migrations\` discovery,
|
|
252
|
+
\`observe.spec_migration\` evidence, and guarded source retirement instead of
|
|
253
|
+
direct table, stage, or view changes. \`admin.cancel_spec_migration\` is only a
|
|
254
|
+
pre-activation abandonment path, not rollback.
|
|
211
255
|
In co-development mode, keep the spec track and app track visible side by side.`;
|
|
212
256
|
}
|
|
213
257
|
|