Skip to content

Schema authorization: full coverage + correctness fixes + hub parity (0192) - #139

Merged
crs48 merged 7 commits into
mainfrom
feat/schema-authorization-coverage-0192
Jun 17, 2026
Merged

Schema authorization: full coverage + correctness fixes + hub parity (0192)#139
crs48 merged 7 commits into
mainfrom
feat/schema-authorization-coverage-0192

Conversation

@crs48

@crs48 crs48 commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Implements the safe, high-value core of exploration 0192 (schema authorization coverage & enforcement audit). The audit found that only ~12 of ~64 schemas declared an authorization block and that the policy engine had latent lockout bugs. This PR closes the coverage gap and fixes the correctness bugs, leaving the schema layer complete, correct, and ready to be wired — with zero production behavior change (the client evaluator is still unwired; the hub remains the sole enforcer today).

What's in this PR

Correctness (the landmines)

Coverage — every content schema now declares a policy

  • 9 schemas with a space relation inherit via spaceCascadeAuthorization().
  • 9 child types inherit from their parent: database-row/field/select-option/view + saved-viewdatabase; chat-messagechannel; comment/reactiontarget; task-viewproject.
  • 6 standalone/personal types (folder, tag, external-reference, media-asset, inbox-state, user-widget) are owner-only via presets.private().
  • Edge/identity/system nodes (SpaceMembership, Grant, Profile, SchemaDefinition, SchemaCompatibility, SyncPolicy, PresenceSummary) stay intentionally policy-free via a single-source AUTH_EXEMPT_SCHEMA_IRIS allowlist.

Guard rails so coverage can't erode

  • New authorization-coverage.test.ts fails CI if any registered schema is "legacy" and not on the exempt allowlist.
  • defineSchema warns about legacy schemas in the dev server.

Schema ↔ hub parity

  • New schemaToHubPolicy() / hubActionsForSpaceRole() project a schema's authorization onto the hub grant-action vocabulary, with a parity test asserting the Space cascade matches spaceRoleGrantActions for every Space role — so the schema model and hub grant model can't drift silently.

Regression tests lock both landmine fixes.

Verification

  • @xnetjs/data typecheck ✅, build ✅, full auth + schema suite (492 tests incl. 2 new regressions) ✅, eslint + prettier ✅.
  • Additive only (new exports, added authorization metadata) — InferNode types and runtime behavior are unchanged.

Deferred (documented in the exploration as a flag-gated rollout)

  • Wiring createPolicyEvaluator into client NodeStores + swapping in AuthorizedYjsSyncProvider (needs a client-side GrantIndex lifecycle + perf/real-data validation).
  • visibility: 'public'PUBLIC read (needs a per-node conditional resolver; the hub already enforces public).

See docs/explorations/0192_[_]_SCHEMA_AUTHORIZATION_COVERAGE_AND_ENFORCEMENT_AUDIT.md for the full audit, findings, and updated implementation status.

🤖 Generated with Claude Code

xNet Test and others added 7 commits June 17, 2026 08:54
…ent wiring

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The policy evaluator's legacy (authorization-less) branch returned owner-only
*before* the grant-index fallback, so a node shared purely via a hub/share
grant was invisible to its grantees once the evaluator is wired (Landmine #1).
It now consults the grant index for non-owners. The unreachable
`!authorization` deny branch is removed (getAuthMode already returns 'legacy').

computeRecipients had the same owner-only short-circuit for legacy schemas and
never expanded grants for them (Landmine #3); grant recipients are now folded
in on every path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…guard (0192)

Backfills explicit authorization on the 24 content schemas that were 'legacy'
(owner-only) for lack of a block:
- 9 with a Space relation inherit via spaceCascadeAuthorization()
- 9 child types inherit from their parent (database/channel/target/project)
- 6 standalone/personal types are owner-only via presets.private()

Edge/identity/system nodes (SpaceMembership, Grant, Profile, schema/sync/
presence system nodes) stay intentionally policy-free via a single-source
AUTH_EXEMPT_SCHEMA_IRIS allowlist. A new authorization-coverage test fails CI
if any registered schema is legacy and not exempt, and defineSchema warns about
legacy schemas in the dev server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds schemaToHubPolicy()/hubActionsForSpaceRole() projecting a schema's
authorization block onto the hub grant-action vocabulary (read/write/share/
admin), and a parity test asserting the Space cascade matches
spaceRoleGrantActions for every Space role — so the schema model and the hub
grant model can no longer drift apart silently.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Locks the two correctness fixes: the evaluator allows a non-owner with a valid
hub grant on a legacy schema (Landmine #1), and computeRecipients folds grant
recipients into legacy schemas (Landmine #3).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@crs48
crs48 temporarily deployed to pr-139 June 17, 2026 16:25 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #139.

github-actions Bot added a commit that referenced this pull request Jun 17, 2026
@crs48
crs48 merged commit de379ce into main Jun 17, 2026
10 of 11 checks passed
@crs48
crs48 deleted the feat/schema-authorization-coverage-0192 branch June 17, 2026 16:35
github-actions Bot added a commit that referenced this pull request Jun 17, 2026
crs48 pushed a commit that referenced this pull request Jun 17, 2026
…rd (0192)

The merged authorization-coverage guard (PR #139) requires every built-in
schema to declare an authorization block or be exempt. Give Transcription
spaceCascadeAuthorization() — owner-only by default, inherits its home Space's
access when filed into one — matching Metric, since transcripts are equally
sensitive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
crs48 added a commit that referenced this pull request Jun 18, 2026
…193/0194) (#201)

The `changelog-section` required check was only added in #164, so the
0192/0193/0194 feature batch merged before it never got changelog
entries. This backfills the 12 user-facing features that were missing,
each dated to its merge day with its PR number and contributors:

| PR | Entry |
|----|-------|
| #138 | A safer foundation for plugins |
| #145 | One trust model across plugins and Labs |
| #146 | Reliability you can see for managed hubs |
| #148 | Drive your own coding agent from xNet |
| #149 | AI that can act on your workspace |
| #150 | Your Labs become AI tools |
| #152 | Your agent can use your workspace |
| #154 | AI edits, right inside the editor |
| #155 | An agentic dev loop in your terminal |
| #158 | Review AI edits before they apply |
| #159 | Kick off agentic code tasks from xNet |
| #162 | Plugins run on the Labs runtime |

Skipped: PRs already covered by umbrella entries (#142 plugin ecosystem,
#144 extensibility fabric, #147 automated changelog, #163 agent panel,
#180 changelog gallery), internal-only changes (#139 schema authz — zero
user-facing effect), and meta/test/docs PRs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant