feat(hierarchy): M4-1b-ii hierarchy command family, grant evaluation, visibility #1465

Open
fred wants to merge 2 commits from feat/m4-1b-ii-hierarchy-commands into next
Collaborator

Implements brief M4-1B-II (fleet/lanes/webui-audit/M4-1B-II-BRIEF.md): the ratified hierarchy command family per contract 1 (hierarchy-schema.md) and contract 2 (rbac-grant-model.md), on top of the M4-1b-i audit machinery.

Scope

  • Command family (closed, §6.3): 17 routes on HierarchyController — company/estate/platform-project create, rename, transfer, delete; grant create/change/revoke; two ratified reads (granted companies, §2.8 directory). Route inventory test asserts the surface is exactly this enumeration.
  • HierarchyRepository: every mutation is one transaction through appendHierarchyEvent (event + outbox, idempotency replay, causation-linked composite ops — company create emits create + grant_create; delete emits delete + one grant_revoke per cascaded grant; transfer records transfer_from/transfer_to).
  • HierarchyGrantEvaluationService (contract 2 §3): deny-by-default, effective role = max over ancestor-chain user grants, live fail-closed evaluation down to workspaces; team subjects suspended (§1.4); platform admin confers no tenant access (§1.1).
  • Visibility (§2.8/§5.5): companies.visibility column (migration 0020, private default, CHECK), admin-only audited visibility_change with old+new values, closed-field directory listing, §6.7 no-existence-oracle refusals (unauthorized probe ≡ missing node).
  • §1.1 bypass retirement: role-derived MCP scope elevation and command-authorization admin shortcuts removed; specs moved to the granted-scope path.
  • Witnesses: schema (role CHECK vocabulary, visibility class/default), §6.4 commit + rollback legs per mutation class (rollback via pre-seeded conflicting idempotency key), §6.5 authorization, §6.7 oracle indistinguishability, §6.9 visibility, grant-evaluation semantics (chain inheritance, max-role, live revocation, team rows inert).

Evidence

  • gateway: 866 passed / 45 skipped (new: 22-test command integration suite, route inventory, DTO/service specs)
  • db: 63 passed / 34 skipped PGlite leg (real-PG leg runs in CI)
  • lint + tsc --noEmit clean on both packages
Implements brief M4-1B-II (`fleet/lanes/webui-audit/M4-1B-II-BRIEF.md`): the ratified hierarchy command family per contract 1 (hierarchy-schema.md) and contract 2 (rbac-grant-model.md), on top of the M4-1b-i audit machinery. ## Scope - **Command family (closed, §6.3):** 17 routes on `HierarchyController` — company/estate/platform-project create, rename, transfer, delete; grant create/change/revoke; two ratified reads (granted companies, §2.8 directory). Route inventory test asserts the surface is exactly this enumeration. - **`HierarchyRepository`:** every mutation is one transaction through `appendHierarchyEvent` (event + outbox, idempotency replay, causation-linked composite ops — company create emits create + grant_create; delete emits delete + one grant_revoke per cascaded grant; transfer records transfer_from/transfer_to). - **`HierarchyGrantEvaluationService` (contract 2 §3):** deny-by-default, effective role = max over ancestor-chain user grants, live fail-closed evaluation down to workspaces; team subjects suspended (§1.4); platform admin confers no tenant access (§1.1). - **Visibility (§2.8/§5.5):** `companies.visibility` column (migration 0020, private default, CHECK), admin-only audited `visibility_change` with old+new values, closed-field directory listing, §6.7 no-existence-oracle refusals (unauthorized probe ≡ missing node). - **§1.1 bypass retirement:** role-derived MCP scope elevation and command-authorization admin shortcuts removed; specs moved to the granted-scope path. - **Witnesses:** schema (role CHECK vocabulary, visibility class/default), §6.4 commit + rollback legs per mutation class (rollback via pre-seeded conflicting idempotency key), §6.5 authorization, §6.7 oracle indistinguishability, §6.9 visibility, grant-evaluation semantics (chain inheritance, max-role, live revocation, team rows inert). ## Evidence - gateway: 866 passed / 45 skipped (new: 22-test command integration suite, route inventory, DTO/service specs) - db: 63 passed / 34 skipped PGlite leg (real-PG leg runs in CI) - lint + `tsc --noEmit` clean on both packages
fred added 1 commit 2026-08-29 01:00:50 +00:00
Implements the ratified hierarchy command surface per contract 1
(hierarchy-schema.md) and contract 2 (rbac-grant-model.md), brief M4-1B-II:

- HierarchyRepository: the closed command family (company/estate/
  platform-project create/rename/transfer/delete, grant create/change/
  revoke, directory + granted-companies reads). Every mutation runs in one
  transaction through the M4-1b-i audit machinery (event + outbox,
  idempotency-key replay, causation-linked composite operations).
- HierarchyGrantEvaluationService: live deny-by-default evaluation —
  effective role is the max over ancestor-chain user grants, fail-closed,
  team subjects suspended (§1.4), platform admin confers no tenant access
  (§1.1).
- companies.visibility column (private default, directory carve-out) with
  migration 0020, admin-only audited visibility_change (§5.5), closed-field
  directory listing (§2.8), no-existence-oracle refusals (§6.7).
- hierarchy_grants role CHECK pinned to the ratified vocabulary; namespaced
  serialized roles (hierarchy:*, §4.5).
- §1.1 bypass retirement: role-derived MCP scope elevation and hasScope
  admin shortcuts removed; specs updated to the granted-scope path.
- Witnesses: schema-level (role CHECK, visibility class/default), §6.3
  closed route inventory, §6.4 per-mutation-class commit+rollback legs,
  §6.5 authorization, §6.7 oracle indistinguishability, §6.9 visibility,
  grant-evaluation semantics (chain inheritance, max-role, live
  revocation).
fred added 1 commit 2026-08-29 01:22:37 +00:00
GLM round-1 findings on PR #1465:
- BLOCKING 1: remove role-keyed content widening from mcp.service.ts —
  isGlobalAdminActor/isTenantAdminActor/matchesTenant and every
  short-circuit keyed on users.role are gone; project/mission/task
  visibility is ownership + derived membership only, task create scope
  is unconditional. Spec test rewritten to witness that admin-role and
  platform-admin-role actors see only owned content.
- MINOR 2: writer-coverage header updated to the non-empty allowlist.
- MINOR 3: §6.9 witness — a directory-listed company still refuses
  non-granted callers (granted-read exclusion + mutation oracle).
- MINOR 4: §6.4 commit legs for renameCompany (previousName in the
  audited event) and direct revokeGrant (row deletion + grant_revoke).
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
Required
Details
This pull request doesn't have enough required approvals yet. 0 of 1 official approvals granted.
You are not authorized to merge this pull request.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/m4-1b-ii-hierarchy-commands:feat/m4-1b-ii-hierarchy-commands
git checkout feat/m4-1b-ii-hierarchy-commands
Sign in to join this conversation.