Skip to content

Commit 2bee609

Browse files
os-zhuangclaude
andauthored
refactor(spec): remove dead compliance subsystems (ADR-0056 D8) + mark agent visibility EXPERIMENTAL (#1901) (#2693)
ADR-0056 D8 said "design + enforce, or remove" for the declared-but-never- enforced surface. Dispositions: REMOVED (no runtime path ever read them; compliance-grade config must never merely look live): - system/compliance.zod.ts (GDPR/HIPAA/PCI ComplianceConfig) + tests - system/masking.zod.ts (MaskingRule/MaskingConfig) + tests — FLS is the enforced field-visibility path; a masking/deny layer arrives with ADR-0066 ⑦/⑧ if needed - security/rls.zod.ts: RLSConfigSchema / RLSAuditEventSchema / RLSAuditConfigSchema — the enforced RLS path (computeRlsFilter) never read the global config; per-policy RowLevelSecurityPolicySchema is unchanged KEPT [EXPERIMENTAL]: system/encryption.zod.ts — real enterprise roadmap item with a stable shape; carrying it marked costs less than remove-and-re-add (ADR-0087). MARKED [EXPERIMENTAL — NOT ENFORCED] (#1901): AgentSchema.visibility — the chat-access evaluator deliberately excludes it and the list route does not filter by it, so `private` does not hide an agent. Schema description + the authoring form now say so; access/permissions (enforced since #1884) are the real gates. Ledger: authz-conformance matrix rows flipped (3× removed with disposition notes, field-encryption note records the keep decision, new agent-visibility experimental row). Generated reference docs regenerated (compliance/masking pages deleted); hand-written security/types/authorization docs synced. Tests: spec 6659 passed (246 files) after removal; api-surface regenerated; liveness ✓; conformance-matrix companion test ✓; full turbo build green. Refs #2561, ADR-0056 D8, #1901 Claude-Session: https://claude.ai/code/session_0187GeNqezxV6g5jiLiggfbt Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9fa84f9 commit 2bee609

29 files changed

Lines changed: 183 additions & 1746 deletions
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
BREAKING (pre-launch): remove the three declared-but-never-enforced compliance
6+
subsystems per ADR-0056 D8 ("design + enforce, or remove"), and mark the AI
7+
agent `visibility` property EXPERIMENTAL (#1901).
8+
9+
Removed — none of these were read by any runtime path, and compliance-grade
10+
configuration must never merely look live:
11+
12+
- `ComplianceConfigSchema` / `GDPRConfigSchema` / `HIPAAConfigSchema` (and the
13+
rest of `system/compliance.zod.ts`) — there is no data-subject-rights engine,
14+
retention enforcer, or BAA gate. FROM `import { ComplianceConfigSchema } from
15+
'@objectstack/spec/system'` TO: delete the reference — a real compliance
16+
subsystem will be designed top-down when scheduled.
17+
- `MaskingConfigSchema` / `MaskingRuleSchema` (`system/masking.zod.ts`) — no
18+
redaction layer applies them. FROM masking config TO: field-level security
19+
(permission-set field rules, enforced by plugin-security's field masker); a
20+
subtractive masking/deny layer arrives with ADR-0066 ⑦/⑧ if needed.
21+
- `RLSConfigSchema` / `RLSAuditEventSchema` / `RLSAuditConfigSchema`
22+
(`security/rls.zod.ts`) — the enforced RLS path never read the global config.
23+
FROM global `RLSConfig` TO: per-policy `RowLevelSecurityPolicySchema` (the
24+
live, enforced surface — unchanged).
25+
26+
Kept, still `[EXPERIMENTAL]`: `EncryptionConfigSchema` (at-rest field
27+
encryption) — a real enterprise roadmap item with a stable shape; carrying it
28+
marked costs less than remove-and-re-add (ADR-0087).
29+
30+
Marked `[EXPERIMENTAL — NOT ENFORCED]` (#1901): `AgentSchema.visibility` — the
31+
chat-access evaluator deliberately excludes it and the agent list route does
32+
not filter by it, so `private` does not hide an agent. The schema description
33+
and the authoring form now say so; use `access` / `permissions` (both enforced
34+
at the chat route since #1884) for real gating. The ADR-0056 D10 conformance
35+
matrix tracks all dispositions (`agent-visibility` experimental;
36+
`compliance-configs` / `data-masking` / `rls-config-global` removed).

content/docs/permissions/authorization.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ one of two doors, each writing only what it owns:
143143
| 2 · Distribution / install / upgrade / uninstall | Install-consent scopes (ADR-0025 — consent ≠ RBAC grants); namespaced, collision-free composition; provenance axis makes uninstall well-defined | ADR-0025/0028/0048/0086 |
144144
| 3 · Environment composition / assignment | Platform-owned assignment records (`sys_user_role` etc.); anti-escalation; union semantics | ADR-0057 D4 |
145145
| 4 · Runtime enforcement | The six-gate chain above; ~18 primitives enforced and CI-guarded | ADR-0056 D10 matrix |
146-
| 5 · Production / enterprise | Honest `[EXPERIMENTAL]` markers on the unenforced surface (field encryption, masking, compliance configs); enterprise authentication hardening staged per ADR-0069 | ADR-0049/0056 D8, ADR-0069 |
146+
| 5 · Production / enterprise | ADR-0056 D8 dispositions settled (2026-07): compliance configs, data masking, and the global RLSConfig were **removed** (never enforced); field encryption stays honestly `[EXPERIMENTAL]` (roadmap); agent `visibility` is marked `[EXPERIMENTAL]` pending #1901. Enterprise authentication hardening staged per ADR-0069 | ADR-0049/0056 D8, ADR-0069 |
147147

148148
## Governance: how "declared = enforced" is kept true
149149

content/docs/protocol/objectql/security.mdx

Lines changed: 10 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ rowLevelSecurity:
198198
using: "status == 'active'" # date-window/function predicates (NOW(), arithmetic) are NOT pushdown-able (ADR-0055) — enforce time windows in the app layer or a pre-resolved set
199199
```
200200

201-
> RLS conditions are compiled to parameterized queries. The default policy when no rule matches is **deny** (`RLSConfigSchema.defaultPolicy`).
201+
> RLS conditions are compiled to parameterized queries, and the enforcement path fails **closed**: an applicable policy that cannot be compiled denies (returns zero rows) rather than being dropped. (The old global `RLSConfigSchema` was removed in 2026-07 — it was never read by the enforced path; per-policy `RowLevelSecurityPolicySchema` is the live surface.)
202202

203203
---
204204

@@ -251,71 +251,14 @@ fields:
251251

252252
## 4. Data Masking
253253

254-
> **Status: schema exists, field wiring removed.** `MaskingRuleSchema`
255-
> (`packages/spec/src/system/masking.zod.ts`, strategies `redact`, `partial`,
256-
> `hash`, `tokenize`, `randomize`, `nullify`, `substitute`) remains in the
257-
> System namespace, but the per-field `maskingRule` property was **pruned from
258-
> the Field schema in 2026-06** as dead surface — it was never read by the
259-
> runtime (see `docs/audits/2026-06-dead-surface-disposition-plan.md`). To keep
260-
> a value out of reader hands today, use FLS (`readable: false`), `hidden`, or
261-
> a `type: 'secret'` field. The examples below show the *schema shapes* for
262-
> implementers, not a wired runtime capability.
263-
264-
### Partial Masking
265-
266-
```yaml
267-
# user.object.yml
268-
fields:
269-
ssn:
270-
type: text
271-
label: SSN
272-
maskingRule:
273-
field: ssn
274-
strategy: partial
275-
pattern: '\d{5}$' # regex selecting the visible portion
276-
preserveFormat: true
277-
preserveLength: true
278-
exemptRoles: [hr_admin] # roles that see the unmasked value
279-
```
280-
281-
### Full Redaction
282-
283-
```yaml
284-
fields:
285-
credit_card:
286-
type: text
287-
label: Credit Card
288-
maskingRule:
289-
field: credit_card
290-
strategy: redact
291-
```
292-
293-
### Role-Scoped Masking
294-
295-
`roles` lists the roles that see the *masked* value; `exemptRoles` lists those that see the original:
296-
297-
```yaml
298-
fields:
299-
salary:
300-
type: currency
301-
label: Salary
302-
maskingRule:
303-
field: salary
304-
strategy: partial
305-
exemptRoles: [hr_manager, hr_admin]
306-
```
307-
308-
### Hash Masking
309-
310-
```yaml
311-
fields:
312-
email:
313-
type: email
314-
label: Email
315-
maskingRule:
316-
field: email
317-
strategy: hash
318-
```
254+
> **Status: REMOVED (2026-07, ADR-0056 D8 "design + enforce, or remove").**
255+
> `MaskingRuleSchema` / `MaskingConfigSchema` were deleted from the spec: no
256+
> redaction layer ever applied them, and the per-field `maskingRule` property
257+
> had already been pruned in 2026-06. To keep a value out of reader hands, use
258+
> **FLS** (`readable: false` field permissions — enforced by plugin-security's
259+
> field masker), `hidden`, or a `type: 'secret'` field. A subtractive
260+
> masking/deny layer, if needed, arrives with the ADR-0066 ⑦/⑧ muting work.
261+
> Disposition tracked in the ADR-0056 D10 conformance matrix (`data-masking`).
319262

320263
---
321264

@@ -421,7 +364,7 @@ Object- and field-level history is opt-in metadata, not a free-form `enable.audi
421364

422365
- **Field history** — set `trackHistory: true` on the object (`ObjectCapabilities` in `object.zod.ts`) to record per-field changes.
423366
- **Per-field audit trail** — set `auditTrail: true` on an individual field to track every change with user and timestamp.
424-
- **RLS audit** — RLS policy evaluations can be logged via `RLSAuditConfigSchema` (`enabled`, `logLevel`, `destination`, `retentionDays`, …). The recorded event shape is `RLSAuditEventSchema` (timestamp, userId, operation, object, policyName, granted, evaluationDurationMs).
367+
- **RLS audit** — removed (2026-07, ADR-0056 D8): the `RLSAuditConfigSchema`/`RLSAuditEventSchema` shapes were never emitted or read by the runtime RLS path and were deleted from the spec. Enforcement decisions surface today through the security plugin's fail-closed warnings and the standard audit log (`plugin-audit`), not a dedicated RLS event stream.
425368

426369
```yaml
427370
# account.object.yml

content/docs/protocol/objectql/types.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,10 @@ api_key:
950950

951951
> The per-field `maskingRule` and `encryptionConfig` properties were **pruned
952952
> from the Field schema in 2026-06** — they were declared surface with no
953-
> runtime consumer. The `MaskingRuleSchema`/`EncryptionConfigSchema` shapes
954-
> remain in the System namespace for implementers; see
955-
> [Security & Access Control](/docs/protocol/objectql/security) for their status.
953+
> runtime consumer. In 2026-07 the masking shapes were removed from the spec
954+
> entirely (ADR-0056 D8); `EncryptionConfigSchema` remains in the System
955+
> namespace as `[EXPERIMENTAL]` roadmap surface. See
956+
> [Security & Access Control](/docs/protocol/objectql/security) for status.
956957

957958
## Type Selection Guide
958959

content/docs/references/ai/agent.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const result = AIKnowledge.parse(data);
8484
| **access** | `string[]` | optional | Who can chat with this agent |
8585
| **permissions** | `string[]` | optional | Required permissions or roles |
8686
| **tenantId** | `string` | optional | Tenant/Organization ID |
87-
| **visibility** | `Enum<'global' \| 'organization' \| 'private'>` || |
87+
| **visibility** | `Enum<'global' \| 'organization' \| 'private'>` || [EXPERIMENTAL — NOT ENFORCED, #1901] Intended listing scope. No runtime consumer yet; use access/permissions for real gating. |
8888
| **planning** | `Object` | optional | Autonomous reasoning and planning configuration |
8989
| **memory** | `Object` | optional | Agent memory management |
9090
| **guardrails** | `Object` | optional | Safety guardrails for the agent |

content/docs/references/cloud/app-store.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ installing, and managing marketplace apps from within ObjectOS.
2121

2222
## Customer Journey
2323

24-
```mermaid
25-
flowchart LR
26-
Discover --> Evaluate --> Install --> Configure --> Use --> Rate["Rate / Review"] --> Manage
24+
```
25+
26+
Discover → Evaluate → Install → Configure → Use → Rate/Review → Manage
27+
2728
```
2829

2930
## Key Concepts

content/docs/references/cloud/developer-portal.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ Defines schemas for the developer-facing side of the marketplace ecosystem.
1111

1212
Covers the complete developer journey:
1313

14-
```mermaid
15-
flowchart LR
16-
Register --> Create["Create App"] --> Develop --> Validate --> Build --> Submit --> Monitor --> Iterate
14+
```
15+
16+
Register → Create App → Develop → Validate → Build → Submit → Monitor → Iterate
17+
1718
```
1819

1920
## Architecture Alignment

content/docs/references/cloud/marketplace.mdx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,18 @@ platform, and customers who install plugins.
4747

4848
## Platform Management Flow
4949

50-
```mermaid
51-
flowchart LR
52-
A["1 · Receive<br/>accept submissions from verified publishers"] --> B["2 · Scan<br/>automated security + compatibility check"]
53-
B --> C["3 · Review<br/>human review for quality + policy"]
54-
C --> D["4 · Catalog<br/>index in marketplace search"]
55-
D --> E["5 · Monitor<br/>track installs, ratings, issues, SLAs"]
50+
```
51+
52+
1. Receive → Accept submissions from verified publishers
53+
54+
2. Scan → Automated security scan and compatibility check
55+
56+
3. Review → Human review for quality and policy compliance
57+
58+
4. Catalog → Index in marketplace search catalog
59+
60+
5. Monitor → Track installs, ratings, issues, and enforce SLAs
61+
5662
```
5763

5864
<Callout type="info">

content/docs/references/data/field.mdx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Field Type Enum
1414
## TypeScript Usage
1515

1616
```typescript
17-
import { Address, ComputedFieldCache, CurrencyConfig, CurrencyValue, DataQualityRules, FieldType, FileAttachmentConfig, LocationCoordinates, SelectOption, VectorConfig } from '@objectstack/spec/data';
18-
import type { Address, ComputedFieldCache, CurrencyConfig, CurrencyValue, DataQualityRules, FieldType, FileAttachmentConfig, LocationCoordinates, SelectOption, VectorConfig } from '@objectstack/spec/data';
17+
import { Address, ComputedFieldCache, CurrencyConfig, CurrencyValue, DataQualityRules, FieldType, FileAttachmentConfig, LocationCoordinates, VectorConfig } from '@objectstack/spec/data';
18+
import type { Address, ComputedFieldCache, CurrencyConfig, CurrencyValue, DataQualityRules, FieldType, FileAttachmentConfig, LocationCoordinates, VectorConfig } from '@objectstack/spec/data';
1919

2020
// Validate data
2121
const result = Address.parse(data);
@@ -194,20 +194,6 @@ const result = Address.parse(data);
194194
| **accuracy** | `number` | optional | Accuracy in meters |
195195

196196

197-
---
198-
199-
## SelectOption
200-
201-
### Properties
202-
203-
| Property | Type | Required | Description |
204-
| :--- | :--- | :--- | :--- |
205-
| **label** | `string` || Display label (human-readable, any case allowed) |
206-
| **value** | `string` || Stored value (lowercase machine identifier) |
207-
| **color** | `string` | optional | Color code for badges/charts |
208-
| **default** | `boolean` | optional | Is default option |
209-
210-
211197
---
212198

213199
## VectorConfig

content/docs/references/data/object.mdx

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ API Operations Enum
1414
## TypeScript Usage
1515

1616
```typescript
17-
import { ApiMethod, Index, ObjectAccessConfig, ObjectCapabilities, ObjectExternalBinding, ObjectFieldGroup, ObjectOwnershipEnum, SoftDeleteConfig, TenancyConfig, VersioningConfig } from '@objectstack/spec/data';
18-
import type { ApiMethod, Index, ObjectAccessConfig, ObjectCapabilities, ObjectExternalBinding, ObjectFieldGroup, ObjectOwnershipEnum, SoftDeleteConfig, TenancyConfig, VersioningConfig } from '@objectstack/spec/data';
17+
import { ApiMethod, Index, ObjectAccessConfig, ObjectCapabilities, ObjectExternalBinding, ObjectFieldGroup, ObjectOwnershipEnum, ObjectRequiredPermissions, PerOperationRequiredPermissions, SoftDeleteConfig, TenancyConfig, VersioningConfig } from '@objectstack/spec/data';
18+
import type { ApiMethod, Index, ObjectAccessConfig, ObjectCapabilities, ObjectExternalBinding, ObjectFieldGroup, ObjectOwnershipEnum, ObjectRequiredPermissions, PerOperationRequiredPermissions, SoftDeleteConfig, TenancyConfig, VersioningConfig } from '@objectstack/spec/data';
1919

2020
// Validate data
2121
const result = ApiMethod.parse(data);
@@ -135,6 +135,48 @@ External datasource binding (ADR-0015)
135135
* `extend`
136136

137137

138+
---
139+
140+
## ObjectRequiredPermissions
141+
142+
### Union Options
143+
144+
This schema accepts one of the following structures:
145+
146+
#### Option 1
147+
148+
Type: `string[]`
149+
150+
---
151+
152+
#### Option 2
153+
154+
### Properties
155+
156+
| Property | Type | Required | Description |
157+
| :--- | :--- | :--- | :--- |
158+
| **read** | `string[]` | optional | Capabilities required to read (find/findOne/count/aggregate). |
159+
| **create** | `string[]` | optional | Capabilities required to create (insert). |
160+
| **update** | `string[]` | optional | Capabilities required to update (update/transfer/restore). |
161+
| **delete** | `string[]` | optional | Capabilities required to delete (delete/purge). |
162+
163+
---
164+
165+
166+
---
167+
168+
## PerOperationRequiredPermissions
169+
170+
### Properties
171+
172+
| Property | Type | Required | Description |
173+
| :--- | :--- | :--- | :--- |
174+
| **read** | `string[]` | optional | Capabilities required to read (find/findOne/count/aggregate). |
175+
| **create** | `string[]` | optional | Capabilities required to create (insert). |
176+
| **update** | `string[]` | optional | Capabilities required to update (update/transfer/restore). |
177+
| **delete** | `string[]` | optional | Capabilities required to delete (delete/purge). |
178+
179+
138180
---
139181

140182
## SoftDeleteConfig

0 commit comments

Comments
 (0)