@reunionstudio/airlock-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.agents/skills/airlock-mcp/SKILL.md +122 -0
  2. package/.agents/skills/airlock-mcp/agents/openai.yaml +4 -0
  3. package/LICENSE +187 -0
  4. package/README.md +126 -0
  5. package/SECURITY.md +31 -0
  6. package/bin/airlock-mcp.mjs +5 -0
  7. package/docs/architecture.md +82 -0
  8. package/docs/install-surface.md +112 -0
  9. package/docs/ooda-loop.md +40 -0
  10. package/docs/spec-workbench-architecture.md +161 -0
  11. package/docs/spec-workspace.md +33 -0
  12. package/docs/workflows.md +229 -0
  13. package/package.json +46 -0
  14. package/patterns/blank/README.md +14 -0
  15. package/patterns/blank/sample.records.json +19 -0
  16. package/patterns/blank/spec.config.json +72 -0
  17. package/patterns/guest-access/individual-isolation.md +27 -0
  18. package/patterns/guest-access/role-isolation.md +26 -0
  19. package/patterns/guest-access/shared-contribution.md +25 -0
  20. package/patterns/manifest.json +16 -0
  21. package/patterns/spec-types/commitment.md +24 -0
  22. package/patterns/spec-types/observation.md +22 -0
  23. package/patterns/spec-types/reconciliation.md +19 -0
  24. package/patterns/spec-types/reference-master-data.md +21 -0
  25. package/patterns/starter-posts/README.md +32 -0
  26. package/patterns/starter-posts/sample.records.json +27 -0
  27. package/patterns/starter-posts/spec.config.json +135 -0
  28. package/schemas/airlock-mcp-workspace.schema.json +14 -0
  29. package/setup.py +41 -0
  30. package/src/airlock_mcp/__init__.py +3 -0
  31. package/src/airlock_mcp/__main__.py +5 -0
  32. package/src/airlock_mcp/art.py +26 -0
  33. package/src/airlock_mcp/bootstrap.py +161 -0
  34. package/src/airlock_mcp/cli.py +450 -0
  35. package/src/airlock_mcp/jsonio.py +56 -0
  36. package/src/airlock_mcp/manage.py +247 -0
  37. package/src/airlock_mcp/models.py +43 -0
  38. package/src/airlock_mcp/patterns.py +49 -0
  39. package/src/airlock_mcp/project.py +39 -0
  40. package/src/airlock_mcp/records.py +43 -0
  41. package/src/airlock_mcp/specs.py +110 -0
  42. package/src/airlock_mcp/sql.py +15 -0
  43. package/src/airlock_mcp/summary.py +115 -0
  44. package/src/airlock_mcp/updater.py +76 -0
  45. package/src/airlock_mcp/validation.py +334 -0
  46. package/src/airlock_mcp/workspace.py +223 -0
  47. package/src/cli.mjs +89 -0
  48. package/src/install.mjs +100 -0
  49. package/src/mcp.mjs +184 -0
  50. package/src/text.mjs +108 -0
  51. package/src/workbench.mjs +368 -0
  52. package/workspaces/_template/brief.md +18 -0
  53. package/workspaces/_template/decisions.md +40 -0
  54. package/workspaces/_template/questions.md +9 -0
  55. package/workspaces/_template/review.md +21 -0
  56. package/workspaces/_template/sample.records.json +19 -0
  57. package/workspaces/_template/spec.config.json +72 -0
@@ -0,0 +1,40 @@
1
+ # OODA Loop For Airlock Specs
2
+
3
+ Airlock specs should support a business loop, not just a table.
4
+
5
+ ## Observe
6
+
7
+ Name the evidence and systems that matter:
8
+
9
+ - human entries
10
+ - agent observations
11
+ - screenshots, PDFs, receipts, exports, or source files
12
+ - source APIs or app objects
13
+ - existing Airlock specs or reference data
14
+ - downstream system state
15
+
16
+ ## Orient
17
+
18
+ Turn observations into a governed shape:
19
+
20
+ - one row grain
21
+ - durable identifiers
22
+ - business timestamps
23
+ - typed fields
24
+ - validated variants
25
+ - attachments
26
+ - guest access
27
+ - workflow
28
+ - references
29
+ - expectations
30
+
31
+ ## Decide
32
+
33
+ Choose the smallest governed output worth creating now. If uncertainty is high,
34
+ start with `posts` and let real feedback shape the next spec.
35
+
36
+ ## Act
37
+
38
+ Create the spec in Airlock only after local drafting is coherent. Then collect
39
+ records, review them, and decide whether to revise the spec or add the next
40
+ small spec.
@@ -0,0 +1,161 @@
1
+ # Architecture
2
+
3
+ Airlock MCP is intentionally small:
4
+
5
+ - Codex is the conversational interface.
6
+ - The repo is the durable workspace.
7
+ - The CLI is deterministic local tooling.
8
+ - Airlock stored procedures remain the authority for live validation and
9
+ mutation.
10
+
11
+ ## Module Boundaries
12
+
13
+ - `cli.py`: argument parsing and command dispatch only.
14
+ - `art.py`: small terminal identity and about text.
15
+ - `bootstrap.py`: specs-repo bootstrap files, including `AGENTS.md` and the
16
+ repo-scoped Codex skill.
17
+ - `manage.py`: workspace discovery, archive, restore, rename, and next-action
18
+ helpers.
19
+ - `project.py`: checkout discovery and environment override handling.
20
+ - `patterns.py`: pattern manifest loading.
21
+ - `workspace.py`: create, import, and clone workspace file operations.
22
+ - `specs.py`: spec-config extraction, identity retitling, and sample-record
23
+ generation.
24
+ - `records.py`: deterministic records JSON to CSV rendering.
25
+ - `summary.py`: compact workspace recap for session re-entry.
26
+ - `updater.py`: self-update planning and execution.
27
+ - `validation.py`: local workspace and records checks.
28
+ - `sql.py`: validate-only SQL rendering.
29
+ - `jsonio.py`: JSON/text file helpers.
30
+
31
+ Keep product data in `patterns/`, workspace templates in `workspaces/_template/`,
32
+ and Airlock-specific validation rules in `validation.py`. Do not put another
33
+ copy of a pattern into Python code.
34
+
35
+ ## Source-Of-Truth Rules
36
+
37
+ `patterns/manifest.json` lists CLI-visible starter patterns. Each listed
38
+ pattern directory must include:
39
+
40
+ - `README.md`
41
+ - `spec.config.json`
42
+ - `sample.records.json`
43
+
44
+ The CLI reads those files directly. That makes pattern edits reviewable as data
45
+ changes instead of code changes.
46
+
47
+ ## Create, Import, Clone
48
+
49
+ The old Airlock Streamlit editor used mode-specific hydration:
50
+
51
+ - create: start from defaults
52
+ - edit: hydrate canonical config and preserve unmodeled sections
53
+ - clone: hydrate source config, but blank/reset identity fields
54
+
55
+ Airlock MCP maps that to files:
56
+
57
+ - `init-repo`: prepare a separate specs repo for Codex and Airlock MCP
58
+ - `init`: create from a pattern
59
+ - `import-spec`: edit/import an existing canonical or spec-library config in a
60
+ new workspace
61
+ - `clone`: copy a workspace, reset `core_config.spec_name` and
62
+ `core_config.spec_alias`, and regenerate sample records
63
+ - `rename`: move a workspace and, by default, retitle its spec identity
64
+ - `archive` and `restore`: move drafts in and out of `_archive`
65
+ - `list-workspaces`: show active drafts, with archived drafts available via
66
+ `--all`
67
+
68
+ This repo does not try to be the installed Airlock editor. It gives Codex and
69
+ humans a careful drafting surface before Airlock receives the final config.
70
+
71
+ ## Update Boundary
72
+
73
+ `self-update` supports two intentionally simple paths:
74
+
75
+ - checkout mode: `git pull --ff-only`
76
+ - installed package mode: `pip install --upgrade <source>`
77
+
78
+ The command prints the selected plan first, supports `--dry-run`, and refuses a
79
+ git checkout with uncommitted changes unless `--force` is passed. Keep update
80
+ logic in `updater.py`; do not hide network or package-manager side effects in
81
+ other commands.
82
+
83
+ ## Validation Boundary
84
+
85
+ Local checks catch:
86
+
87
+ - missing workspace files
88
+ - invalid JSON
89
+ - missing core fields
90
+ - duplicate columns
91
+ - unsupported column types
92
+ - missing date/datetime strftime formats
93
+ - `variant_shape` rules pointing at non-variant columns
94
+ - variant columns with no `variant_shape` rule
95
+ - shared guest-role access levels without matching enabled public subfolders
96
+ - sample records with undeclared or missing required fields
97
+ - payload fields that look like Airlock workflow/reviewer state
98
+
99
+ Local checks do not prove that installed Airlock will accept a spec. Always use
100
+ installed Airlock validation before mutation.
101
+
102
+ ## Records Boundary
103
+
104
+ `sample.records.json` is the authoring shape. It supports nested JSON for
105
+ variant fields and is easy for Codex to patch over multiple sessions.
106
+
107
+ `export-csv` is the handoff adapter. It writes fields in `column_config` order,
108
+ ignores undeclared extras after validation has reported them, and serializes
109
+ objects or arrays as compact JSON strings. Keep other record-format adapters in
110
+ `records.py` so the CLI stays thin.
111
+
112
+ ## Install Boundary
113
+
114
+ The public install surface is expected to be Airlock MCP shaped:
115
+
116
+ ```bash
117
+ npx @reunionstudio/airlock-mcp install
118
+ ```
119
+
120
+ The connector implementation belongs in `reunionstudio/airlock-mcp`. Airlock
121
+ MCP is the single installed interface for agents working with Airlock: building
122
+ specs, using specs to pull and push governed data, and capturing improvements
123
+ from real use cases. This workbench owns the spec-building implementation:
124
+ patterns, bootstrap, workspace files, local checks, and the Codex skill.
125
+
126
+ That command is the agent connector/setup entry point, not the user's spec
127
+ workspace. After installing or registering the connector, the user still creates
128
+ a separate `<project>-specs` repo and works there with Codex. Users should ask
129
+ for Airlock, not install a separate spec-building tool.
130
+
131
+ For Codex, the install command should use the platform MCP manager rather than
132
+ editing config files directly:
133
+
134
+ ```bash
135
+ codex mcp add airlock -- npx -y @reunionstudio/airlock-mcp server
136
+ ```
137
+
138
+ The npm package is an installer and launcher. The production MCP server can be
139
+ Rust when Airlock MCP grows beyond bootstrap guidance. If implemented with
140
+ stdio, stdout must remain protocol-only and all logging must go to stderr.
141
+
142
+ The current dogfood/development path can install Airlock MCP into the specs
143
+ repo before the MCP package is published, then run:
144
+
145
+ ```bash
146
+ airlock-mcp init-repo
147
+ ```
148
+
149
+ That command writes the Codex-facing repo instructions and skill into the specs
150
+ repo. Keep those bootstrap assets as files, not generated prose hidden in the
151
+ CLI, so product guidance remains reviewable.
152
+
153
+ The normal development path for Airlock MCP itself is from a checkout:
154
+
155
+ ```bash
156
+ python3 -m pip install -e .
157
+ ```
158
+
159
+ The CLI discovers the checkout by walking upward for `patterns/manifest.json`.
160
+ Set `AIRLOCK_MCP_HOME=/path/to/airlock-mcp` if the command is launched from
161
+ another working directory.
@@ -0,0 +1,33 @@
1
+ # Spec Workspace Files
2
+
3
+ Every draft workspace should preserve context for future Codex sessions.
4
+
5
+ - `brief.md`: business goal, users, systems, and first useful outcome.
6
+ - `decisions.md`: row grain, evidence, access, workflow, references, and OODA
7
+ decisions.
8
+ - `questions.md`: unresolved questions that materially affect the model.
9
+ - `spec.config.json`: draft full Airlock admin spec config.
10
+ - `sample.records.json`: example records in agent-friendly records JSON.
11
+ - `review.md`: local review notes, Airlock validation results, and next steps.
12
+
13
+ The workspace is intentionally plain files. Diffs are the design history.
14
+
15
+ Use `airlock-mcp summary <workspace>` to re-enter a draft. Use
16
+ `airlock-mcp next <workspace>` to choose the next conservative action. Use
17
+ `airlock-mcp export-csv <workspace>` to render `sample.records.json` in the
18
+ CSV shape Airlock loading paths commonly expect. Do not treat the CSV as the
19
+ source of truth; edit the JSON and regenerate it.
20
+
21
+ Use `airlock-mcp rename`, `archive`, and `restore` to organize draft folders.
22
+ `rename` retitles spec identity by default; pass `--keep-spec-identity` for a
23
+ pure folder move.
24
+
25
+ `review.md` should identify the workspace source mode:
26
+
27
+ - `create`: started from an Airlock MCP pattern
28
+ - `import`: hydrated from an existing spec JSON shape such as `specConfig` or
29
+ exported `SPEC_CONFIG`
30
+ - `clone`: copied from another workspace with spec identity reset
31
+
32
+ For clone and import flows, preserve the source path/name so future sessions can
33
+ tell whether changes are deliberate adaptations or accidental drift.
@@ -0,0 +1,229 @@
1
+ # Workflows
2
+
3
+ ## Start A New Specs Repo
4
+
5
+ Use this when a person opens a blank Codex project and wants to start working
6
+ with real Airlock specs. The project repo is where they work. Public users
7
+ should come through the single Airlock MCP install; this repo provides the
8
+ spec-building capability behind that experience.
9
+
10
+ Ask for the project or organization name first, then lowercase it, replace
11
+ spaces with hyphens, and append `-specs`. For example, `Home` becomes
12
+ `home-specs`. Reserve `airlock-specs` for the canonical reusable spec library.
13
+ Airlock itself does not create this repo; Codex can create it locally while
14
+ helping the user start an Airlock specs project.
15
+ Start in Codex, not Snowflake Cortex. Snow CLI or Cortex only matters later when
16
+ validating, creating, or operating specs against an installed Airlock app.
17
+
18
+ The preferred Codex prompt is:
19
+
20
+ ```text
21
+ I want to use Airlock MCP to start working with Airlock specs for Home.
22
+
23
+ Set up this project as an Airlock specs repo. Use the Airlock MCP
24
+ spec-building capability when we need to draft or revise specs. Welcome me,
25
+ help me think through real Airlock use cases, and ask only for the missing
26
+ decisions. Do not create the first workspace until I choose a path.
27
+ ```
28
+
29
+ When dogfooding this implementation repo before the MCP package is published,
30
+ Codex can install the spec-building workbench from GitHub:
31
+
32
+ ```bash
33
+ git init
34
+ python3 -m venv .venv
35
+ source .venv/bin/activate
36
+ python3 -m pip install git+https://github.com/reunionstudio/airlock-mcp.git
37
+ airlock-mcp init-repo
38
+ ```
39
+
40
+ This does not require a PyPI release. `pip` installs the package directly from
41
+ GitHub. It is a dogfood/developer path, not the public primary install.
42
+
43
+ The target public install shape should be:
44
+
45
+ ```bash
46
+ npx @reunionstudio/airlock-mcp install
47
+ ```
48
+
49
+ The connector implementation lives in `reunionstudio/airlock-mcp`; this
50
+ workbench keeps the Airlock MCP spec-building capability.
51
+
52
+ That should install or register the Airlock MCP connector for the user's agent
53
+ environment. After that, the user still creates a blank `<slug>-specs` project
54
+ and starts chatting there. Airlock MCP covers building specs, using specs to
55
+ pull and push governed data, and improving specs from real use cases.
56
+
57
+ For Codex, the install command should register the server with:
58
+
59
+ ```bash
60
+ codex mcp add airlock -- npx -y @reunionstudio/airlock-mcp server
61
+ ```
62
+
63
+ The MCP-style flow should be:
64
+
65
+ 1. Run `npx @reunionstudio/airlock-mcp install` once for the agent environment.
66
+ 2. Open Codex.
67
+ 3. Create a new blank project named for the org or project, such as
68
+ `home-specs`.
69
+ 4. Tell Codex: `Use Airlock to help me build and use specs.`
70
+ 5. Airlock MCP welcomes, offers OODA brainstorming, a known-process draft, a
71
+ `posts` feedback loop, or installed-Airlock validation/use.
72
+
73
+ `init-repo` creates `AGENTS.md`, `.agents/skills/airlock-mcp/SKILL.md`, and
74
+ `workspaces/`. That is what lets Codex understand prompts such as
75
+ `Use $airlock-mcp` inside the specs repo.
76
+
77
+ After bootstrap, offer three paths before creating a workspace:
78
+
79
+ - brainstorm possible specs using the OODA loop
80
+ - start from a known process and create a blank workspace
81
+ - create a `posts` feedback loop for humans and agents to submit requests,
82
+ observations, and responses
83
+
84
+ ## Start From Feedback
85
+
86
+ Use this when the user chooses a shared feedback loop for humans and agents.
87
+ If they are not sure what to model yet, offer OODA brainstorming before creating
88
+ this workspace.
89
+
90
+ ```bash
91
+ airlock-mcp init feedback-loop --pattern posts
92
+ airlock-mcp check workspaces/feedback-loop
93
+ ```
94
+
95
+ Then ask Codex to help decide what the posts should observe, who responds, and
96
+ what next spec should grow from the feedback.
97
+
98
+ ## Start From A Known Process
99
+
100
+ Use this when the process is known but the data shape is not.
101
+
102
+ ```bash
103
+ airlock-mcp init weekly-timesheets --pattern blank
104
+ ```
105
+
106
+ Replace the draft columns once row grain, event timestamps, typed fields,
107
+ evidence, access, and workflow are clear.
108
+
109
+ ## Import An Existing Spec
110
+
111
+ Use this for an Airlock spec-library file, exported `SPEC_CONFIG`, or a canonical
112
+ config from another repo.
113
+
114
+ ```bash
115
+ airlock-mcp import-spec ../airlock-specs/specs/internal/posts.json imported-posts
116
+ airlock-mcp check workspaces/imported-posts
117
+ ```
118
+
119
+ Supported input shapes:
120
+
121
+ - `{"specConfig": {...}}`
122
+ - `{"spec_config": {...}}`
123
+ - `{"SPEC_CONFIG": "{...}"}`
124
+ - a raw canonical object with `core_config` or `column_config`
125
+ - a legacy `{"specs": [{"config": ...}]}`
126
+
127
+ ## Clone A Workspace
128
+
129
+ Use this when a related spec should preserve most design choices but needs a new
130
+ identity.
131
+
132
+ ```bash
133
+ airlock-mcp clone workspaces/imported-posts team-posts
134
+ airlock-mcp check workspaces/team-posts
135
+ ```
136
+
137
+ Clone resets `core_config.spec_name`, `core_config.spec_alias`, and sample
138
+ records. It keeps the surrounding brief and decisions so Codex can adapt them.
139
+
140
+ ## Organize Workspaces
141
+
142
+ Use this when a workbench has more than one draft in motion.
143
+
144
+ ```bash
145
+ airlock-mcp list-workspaces
146
+ airlock-mcp list-workspaces --all
147
+ airlock-mcp rename workspaces/weekly-timesheets weekly-time-entries
148
+ airlock-mcp archive workspaces/old-draft
149
+ airlock-mcp restore workspaces/_archive/old-draft
150
+ ```
151
+
152
+ `rename` retitles `core_config.spec_name`, `core_config.spec_alias`, and sample
153
+ record spec names by default so the folder and spec identity stay together. Use
154
+ `--keep-spec-identity` when the move is purely organizational.
155
+
156
+ `archive` moves a workspace under `_archive`. `list-workspaces` hides internal
157
+ underscore directories by default and shows archived drafts with `--all`.
158
+
159
+ ## Resume A Session
160
+
161
+ Use this at the start of a later Codex session before changing JSON.
162
+
163
+ ```bash
164
+ airlock-mcp summary workspaces/team-posts
165
+ airlock-mcp next workspaces/team-posts
166
+ ```
167
+
168
+ The summary shows the current spec identity, required fields, variant fields,
169
+ attachment posture, guest access model, sample record count, note-file status,
170
+ and local check counts.
171
+
172
+ `next` prints the same recap plus a conservative next action: fix local errors,
173
+ review warnings, fill open design prompts in `decisions.md`, add sample records,
174
+ or prepare export and validate-only SQL. Inline answers such as
175
+ `One row is: a submitted receipt` count as filled.
176
+
177
+ ## Export Sample Records
178
+
179
+ Use this when the JSON examples should be reviewed or loaded through an
180
+ Airlock CSV-oriented path.
181
+
182
+ ```bash
183
+ airlock-mcp export-csv workspaces/team-posts
184
+ airlock-mcp export-csv workspaces/team-posts --output /tmp/team-posts.csv
185
+ ```
186
+
187
+ `sample.records.json` remains the authoring shape because it is easier for
188
+ Codex and humans to edit. `export-csv` writes columns in `column_config` order
189
+ and serializes `variant` values as compact JSON strings.
190
+
191
+ ## Render Validate-Only SQL
192
+
193
+ Use this as a handoff artifact for an admin or agent with Snowflake access.
194
+
195
+ ```bash
196
+ airlock-mcp render-sql workspaces/team-posts
197
+ airlock-mcp render-sql workspaces/team-posts --operation alter
198
+ ```
199
+
200
+ The rendered SQL uses `validate_only => TRUE` positionally. Review installed
201
+ Airlock documentation before changing it to a mutating call.
202
+
203
+ ## Update The Workbench
204
+
205
+ Use dry-run first so the command is visible before anything changes.
206
+
207
+ ```bash
208
+ airlock-mcp self-update --dry-run
209
+ airlock-mcp self-update
210
+ ```
211
+
212
+ From a checkout, `self-update` uses `git pull --ff-only` and refuses to run with
213
+ uncommitted changes unless `--force` is passed. From an installed package, it
214
+ uses `pip install --upgrade` with the configured source.
215
+
216
+ ## Session Rhythm
217
+
218
+ 1. Run `airlock-mcp check <workspace>`.
219
+ 2. Run `airlock-mcp summary <workspace>` and `airlock-mcp next <workspace>`
220
+ to re-enter the draft.
221
+ 3. Use `airlock-mcp list-workspaces` when choosing which draft to resume.
222
+ 4. Ask Codex to read the workspace and continue the draft.
223
+ 5. Update `decisions.md` before changing `spec.config.json` when a decision
224
+ affects row grain, evidence, business time, access, workflow, or references.
225
+ 6. Keep `questions.md` for decisions that need the human.
226
+ 7. Use `review.md` for local check results, Airlock validation results, and the
227
+ next safe action.
228
+ 8. Export CSV only after the local checker is clean or the exception is
229
+ deliberate and recorded.
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@reunionstudio/airlock-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Single-install MCP interface for Airlock agents.",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/reunionstudio/airlock-mcp.git"
9
+ },
10
+ "homepage": "https://github.com/reunionstudio/airlock-mcp#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/reunionstudio/airlock-mcp/issues"
13
+ },
14
+ "keywords": [
15
+ "airlock",
16
+ "mcp",
17
+ "codex",
18
+ "agents",
19
+ "specs"
20
+ ],
21
+ "bin": {
22
+ "airlock-mcp": "bin/airlock-mcp.mjs"
23
+ },
24
+ "scripts": {
25
+ "test": "node test/smoke.mjs"
26
+ },
27
+ "files": [
28
+ "bin",
29
+ "docs",
30
+ "src",
31
+ ".agents",
32
+ "patterns",
33
+ "schemas",
34
+ "workspaces",
35
+ "setup.py",
36
+ "README.md",
37
+ "SECURITY.md"
38
+ ],
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "license": "Apache-2.0",
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }
@@ -0,0 +1,14 @@
1
+ # Starter Pattern: Blank Draft
2
+
3
+ Use `blank` when the user already has a process in mind and needs a small,
4
+ neutral observation-style starting point.
5
+
6
+ This pattern keeps the first draft intentionally plain:
7
+
8
+ - one stable record id
9
+ - one business timestamp
10
+ - one summary
11
+ - one validated `variant` context field
12
+
13
+ Replace the draft columns once the row grain and typed business facts are clear.
14
+ Do not keep this shape just because it is convenient.
@@ -0,0 +1,19 @@
1
+ {
2
+ "spec_name": "draft_spec",
3
+ "filename": "draft_001",
4
+ "records": [
5
+ {
6
+ "record_id": "REC-001",
7
+ "observed_at": "2026-06-13 09:00:00",
8
+ "summary": "Example draft record.",
9
+ "details": {
10
+ "source": {
11
+ "system": "manual"
12
+ },
13
+ "notes": {
14
+ "reason": "Used to test the draft shape."
15
+ }
16
+ }
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "core_config": {
3
+ "spec_name": "draft_spec",
4
+ "spec_alias": "Draft Spec",
5
+ "description": "Draft Airlock spec.",
6
+ "owner_role": "app_admin",
7
+ "is_published": false,
8
+ "is_archived": false
9
+ },
10
+ "column_config": [
11
+ {
12
+ "name": "record_id",
13
+ "type": "string",
14
+ "description": "Stable record identifier.",
15
+ "tests": ["not_null", "unique"]
16
+ },
17
+ {
18
+ "name": "observed_at",
19
+ "type": "datetime",
20
+ "description": "Business timestamp for the observed event.",
21
+ "format": "%Y-%m-%d %H:%M:%S",
22
+ "tests": ["not_null"]
23
+ },
24
+ {
25
+ "name": "summary",
26
+ "type": "string",
27
+ "description": "Short business-readable summary.",
28
+ "tests": ["not_null"]
29
+ },
30
+ {
31
+ "name": "details",
32
+ "type": "variant",
33
+ "description": "Optional validated context.",
34
+ "tests": []
35
+ }
36
+ ],
37
+ "rules": [
38
+ {
39
+ "type": "variant_shape",
40
+ "field": "details",
41
+ "allowed_root_keys": ["source", "notes"],
42
+ "paths": [
43
+ {
44
+ "json_path": "$.source.system",
45
+ "type": "string",
46
+ "required": false
47
+ },
48
+ {
49
+ "json_path": "$.notes.reason",
50
+ "type": "string",
51
+ "required": false
52
+ }
53
+ ]
54
+ }
55
+ ],
56
+ "file_rules": {
57
+ "file_format": {
58
+ "file_type": "csv",
59
+ "record_delimiter": "\n",
60
+ "field_delimiter": ",",
61
+ "field_optionally_enclosed_by": "\"",
62
+ "escape_unenclosed_field": "\\",
63
+ "encoding": "UTF8",
64
+ "parse_header": true,
65
+ "save_header": true
66
+ }
67
+ },
68
+ "attachment_policy": {
69
+ "attachments_enabled": true,
70
+ "attachment_required": false
71
+ }
72
+ }
@@ -0,0 +1,27 @@
1
+ # Guest Access: Individual Isolation
2
+
3
+ Use this when each person or agent should submit into an isolated path and
4
+ should not see another submitter's files.
5
+
6
+ Good fit:
7
+
8
+ - reimbursements by employee
9
+ - private intake drafts
10
+ - delegated assistant work for one principal
11
+ - sensitive observations where cross-user visibility is risky
12
+
13
+ Design notes:
14
+
15
+ - Enable isolated directories.
16
+ - Give each guest role the narrowest useful access level.
17
+ - Keep manager, reviewer, or owner visibility in Airlock roles rather than
18
+ payload columns.
19
+ - Use delegation when an agent acts for a specific person. Do not impersonate
20
+ the human by reusing their role assignment.
21
+
22
+ Questions to answer:
23
+
24
+ - Who owns the submitted record after review?
25
+ - Does a reviewer need managed-role visibility across isolated submitters?
26
+ - Can the submitter read returned drafts, approved files, or only their own
27
+ working path?
@@ -0,0 +1,26 @@
1
+ # Guest Access: Role Isolation
2
+
3
+ Use this when groups such as departments, store locations, teams, or external
4
+ partners need separate contribution areas.
5
+
6
+ Good fit:
7
+
8
+ - location-level operations logs
9
+ - department budget packets
10
+ - partner submissions
11
+ - team-owned weekly reports
12
+
13
+ Design notes:
14
+
15
+ - Model the group as an Airlock role.
16
+ - Use `managed_by_role` only when a non-admin business role should manage or
17
+ include subordinate roles.
18
+ - Keep role membership and assignment outside the submitted payload.
19
+ - Prefer reference specs for shared project, location, department, or partner
20
+ catalogs.
21
+
22
+ Questions to answer:
23
+
24
+ - Are records owned by the role, by individual contributors, or by both?
25
+ - Does a parent role need read or review visibility?
26
+ - Do role groups share a public read path after approval?