Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1168c4b0d4 | ||
|
|
4f1115d06c | ||
|
|
f988513300 | ||
|
|
82afd633a2 | ||
|
|
903c056b0f | ||
|
|
26b3560ca2 | ||
|
|
6ea6b020f0 | ||
|
|
54f6ccf717 | ||
|
|
6043b9ebff | ||
|
|
f891f78e7b |
@@ -10,8 +10,6 @@ COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
|||||||
COPY apps/appservice/package.json ./apps/appservice/
|
COPY apps/appservice/package.json ./apps/appservice/
|
||||||
COPY packages/ ./packages/
|
COPY packages/ ./packages/
|
||||||
COPY plugins/ ./plugins/
|
COPY plugins/ ./plugins/
|
||||||
# the root prepare script runs scripts/install-hooks.mjs on install
|
|
||||||
COPY scripts/ ./scripts/
|
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN pnpm turbo run build --filter @mosaicstack/mosaic-as...
|
RUN pnpm turbo run build --filter @mosaicstack/mosaic-as...
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,351 +0,0 @@
|
|||||||
# Roll-up Projection Contract (S2 contract 8)
|
|
||||||
|
|
||||||
Status: DRAFT — awaiting ratification (webui-audit S2, contract 8 of 9).
|
|
||||||
Authority: `native-kanban-sot.md` §8 (A1 amendment) — "task and status
|
|
||||||
visualization bubbles up the hierarchy as aggregation over workspaces
|
|
||||||
the reader is authorized on" (§8.1.3); roll-up is never a write and
|
|
||||||
bubble-up views are generated projections, non-authoritative and never
|
|
||||||
import sources (§8.2.2); the express, narrow carve-out from the
|
|
||||||
portfolio-analytics non-goal covers per-workspace task counts and
|
|
||||||
statuses aggregated up the parent chain over readable workspaces, and
|
|
||||||
nothing beyond that boundary (§8.2.4); acceptance requires that roll-up
|
|
||||||
endpoints cannot mutate state and that a reader sees aggregates only
|
|
||||||
over workspaces they are authorized on, with no cross-tenant existence
|
|
||||||
oracles (§8.3). A5 rank 5 names the deliverable: an authorized
|
|
||||||
read-only roll-up query over only readable workspaces, at every
|
|
||||||
hierarchy level, as its own non-mutating query tool, dependent on ranks
|
|
||||||
1–3.
|
|
||||||
|
|
||||||
Revision 2 (terra review F1–F7): membership-only readability is now
|
|
||||||
workspace-local — it contributes at the workspace node only and never
|
|
||||||
promotes ancestor visibility; upward aggregation requires an effective
|
|
||||||
chain role, and §1 defines direct vs effective grants in contract 2's
|
|
||||||
terms (F1). The no-oracle rule gains a defined equivalence predicate
|
|
||||||
(normalized byte equality with an enumerated volatile-field set) and a
|
|
||||||
partial-scope hidden-sibling witness (F2). §2.5 enumerates the closed
|
|
||||||
semantic result and denial schemas field-by-field, including the
|
|
||||||
explicit-zero representation (F3). Cache invalidation, when a cache
|
|
||||||
exists, is witnessed per invalidator class (F4). Non-authoritative and
|
|
||||||
never-gate rules gain an import-graph/data-flow witness, and the
|
|
||||||
mutation check is aligned to contract 1 §6.7's both-table zero-write
|
|
||||||
assertion (F5). The fixture gains a second estate with distinct counts
|
|
||||||
and explicit company-, estate-, project-grant, and membership cases
|
|
||||||
(F6). The §5.3 legacy-row exclusion and pre-rank no-obligation rules
|
|
||||||
are disclosed as drafting additions (F7).
|
|
||||||
|
|
||||||
Revision 3 (terra re-review residuals): the partial-scope witnesses are
|
|
||||||
reconstructed at levels where chain grants can actually differ —
|
|
||||||
platform-project siblings under one estate and estate siblings under
|
|
||||||
one company — because contract 1 §3.1/§3.4 defines no workspace-level
|
|
||||||
grant target, so no reader can hold a chain grant on two of three
|
|
||||||
sibling workspaces (F2). §2.5 now defines one field-exact recursive
|
|
||||||
record — every node, including the queried node and every leaf, is the
|
|
||||||
same five-field shape with a required, deterministically ordered
|
|
||||||
`children` array that is empty at workspaces — and the whole-result
|
|
||||||
rules (no optional fields, denial envelope, wire faithfulness) are
|
|
||||||
their own §2.6 at section scope (F3). The fixture assigns workspaces
|
|
||||||
to named platform-projects, and §6.1's grant-level cases are the three
|
|
||||||
levels contract 1 defines, with workspace-level access covered by the
|
|
||||||
membership case and stated as having no direct chain grant (F6).
|
|
||||||
|
|
||||||
This contract binds the projection semantics (§2), reader authorization
|
|
||||||
semantics (§3), read-only enforcement (§4), dependencies and phase
|
|
||||||
timing (§5), witnesses (§6), and disclosed drafting additions (§7). It
|
|
||||||
defines the roll-up only: hierarchy shape stays with contract 1
|
|
||||||
(`hierarchy-schema.md`), grant vocabulary and evaluation with contract 2
|
|
||||||
(`rbac-grant-model.md`), the task lifecycle and status taxonomy with
|
|
||||||
`native-kanban-sot.md`'s typed surface, and the tool↔Gateway mapping
|
|
||||||
row with contract 5 (`tool-gateway-mapping.md`).
|
|
||||||
|
|
||||||
## 1. Definitions
|
|
||||||
|
|
||||||
1. **Roll-up**: the read-only projection of per-workspace task counts
|
|
||||||
by status, aggregated up the contract 1 parent chain (workspace →
|
|
||||||
platform-project → estate → company).
|
|
||||||
2. **Effective chain role** (at a node, for a reader): the role
|
|
||||||
contract 2 §3 evaluation yields at that node — from a grant on the
|
|
||||||
node itself (a **direct grant**) or from a grant on an ancestor
|
|
||||||
whose domain covers it (an **inherited grant**, contract 2 §3.2).
|
|
||||||
The role vocabulary is contract 2 §2's; this contract adds no role
|
|
||||||
and no new authority source.
|
|
||||||
3. **Chain-readable workspace** (for a reader): a workspace where the
|
|
||||||
reader's effective chain role permits reading task state.
|
|
||||||
4. **Member-readable workspace** (for a reader): a workspace readable
|
|
||||||
only through workspace membership under the SOT's own membership
|
|
||||||
rules (REQ-ID-001), with no effective chain role. Membership
|
|
||||||
confers workspace-local semantics only (contract 2 §3.1, §7.4): it
|
|
||||||
never contributes authority, visibility, or aggregation upward.
|
|
||||||
5. **Aggregation scope** (of a hierarchy node, for a reader): the set
|
|
||||||
of chain-readable workspaces in that node's descendant subtree;
|
|
||||||
plus, when the node is itself a workspace, that workspace if it is
|
|
||||||
chain-readable or member-readable. A member-readable workspace
|
|
||||||
therefore contributes to exactly one node's aggregation scope: its
|
|
||||||
own.
|
|
||||||
6. **Projection**: a generated, non-authoritative view in the sense of
|
|
||||||
`native-kanban-sot.md` §3 invariant 5 — derived from SOT rows,
|
|
||||||
never an import source, never authoritative.
|
|
||||||
|
|
||||||
## 2. Projection semantics
|
|
||||||
|
|
||||||
1. **Aggregate content.** The roll-up for a node reports, per
|
|
||||||
workspace in the reader's aggregation scope and as subtree totals:
|
|
||||||
task counts keyed by the typed lifecycle's status values (owned by
|
|
||||||
`native-kanban-sot.md`; this contract introduces no status), and
|
|
||||||
nothing else. Direct count/status aggregation is the entire
|
|
||||||
surface.
|
|
||||||
2. **Every level.** The roll-up is queryable at workspace,
|
|
||||||
platform-project, estate, and company level. A node's totals equal
|
|
||||||
the sum over its aggregation scope; chain resolution is contract 1
|
|
||||||
§2.5's (every workspace resolves to exactly one chain), so no
|
|
||||||
workspace is counted twice and none is orphaned.
|
|
||||||
3. **Carve-out boundary.** Everything beyond direct count/status
|
|
||||||
aggregation — metrics, trends, forecasting, scoring, velocity,
|
|
||||||
cross-workspace derived analytics, dashboards computed across
|
|
||||||
workspaces — remains a `native-kanban-sot.md` §6 non-goal
|
|
||||||
(§8.2.4). The response schema is closed (§2.5; §6.7 witness):
|
|
||||||
adding any field is an amendment to this contract.
|
|
||||||
4. **Non-authoritative.** No consumer may treat roll-up output as a
|
|
||||||
source of record; it is recomputable at any time from SOT rows and
|
|
||||||
is never imported, persisted as authoritative state, or used to
|
|
||||||
gate or deny work (witness §6.8 — both the write-path and the
|
|
||||||
decision-path prohibitions are witnessed).
|
|
||||||
5. **Closed semantic schema.** The successful result is exactly one
|
|
||||||
**roll-up node record**, a single recursive shape used at every
|
|
||||||
depth. A roll-up node record consists of exactly these five
|
|
||||||
fields, and no others:
|
|
||||||
- `id`: the node's identifier.
|
|
||||||
- `type`: one of the four contract 1 levels.
|
|
||||||
- `name`: the node's name.
|
|
||||||
- `totals`: one entry per status value of the typed lifecycle —
|
|
||||||
every status key present, a count of zero represented explicitly
|
|
||||||
as `0`, never by key absence. At a workspace node, `totals` is
|
|
||||||
that workspace's own counts; at any other node, `totals` is the
|
|
||||||
sum over the node's aggregation scope (§2.2). This is how §2.1's
|
|
||||||
"per workspace and as subtree totals" content is carried:
|
|
||||||
per-workspace counts are the leaf records' `totals`, subtree
|
|
||||||
totals are the interior records' `totals`.
|
|
||||||
- `children`: a required array, present on EVERY node record. Its
|
|
||||||
elements are the reader-visible (§3.2) child nodes of this node,
|
|
||||||
each itself a complete roll-up node record, recursing down to
|
|
||||||
the workspaces in the reader's aggregation scope. At a workspace
|
|
||||||
node the array is exactly `[]` — a workspace record never has
|
|
||||||
children. The array is ordered deterministically, ascending by
|
|
||||||
`id`; the implementing PR asserts that ordering. A node outside
|
|
||||||
§3.2 visibility never appears at any depth.
|
|
||||||
|
|
||||||
The queried node's record IS the whole result — there is no
|
|
||||||
wrapper field around it.
|
|
||||||
|
|
||||||
6. **Whole-result rules.** There are no optional result fields at any
|
|
||||||
depth. The denial/nonexistent response is the contract 5 §4.2
|
|
||||||
not-found-class error envelope with no fields beyond that
|
|
||||||
envelope. The wire DTO is expressed under contract 5 §4.1, and
|
|
||||||
MUST be a faithful serialization of exactly the §2.5 recursive
|
|
||||||
record: a wire field with no corresponding semantic field is a
|
|
||||||
conformance defect.
|
|
||||||
|
|
||||||
## 3. Reader authorization semantics
|
|
||||||
|
|
||||||
1. **Scope rule.** A reader's roll-up over any node aggregates ONLY
|
|
||||||
the reader's aggregation scope (§1.5). An unreadable workspace
|
|
||||||
contributes nothing to any total — not a count, not a row, not a
|
|
||||||
presence marker. A member-readable workspace contributes only at
|
|
||||||
the workspace node itself (§1.4–§1.5): querying it directly
|
|
||||||
succeeds; it never appears in, and never adds to, any ancestor's
|
|
||||||
response for that reader.
|
|
||||||
2. **Node visibility.** A node appears in a roll-up response iff the
|
|
||||||
reader's aggregation scope at that node is non-empty, or the
|
|
||||||
reader holds an effective chain role at the node (§1.2 — direct or
|
|
||||||
inherited; contract 2 §3.2 makes a grant's domain the node and its
|
|
||||||
subtree, so an ancestor grant makes empty descendants visible per
|
|
||||||
the ruling). Per the ruling below, a node with an effective chain
|
|
||||||
role but an empty aggregation scope appears with zero counts.
|
|
||||||
Workspace membership alone never makes any non-workspace node
|
|
||||||
visible. A node where the reader has neither an effective chain
|
|
||||||
role nor a non-empty aggregation scope does not appear at all.
|
|
||||||
3. **No existence oracle.** The response MUST NOT disclose the
|
|
||||||
existence, count, name, or any property of unreadable workspaces
|
|
||||||
or of nodes outside §3.2 visibility — no "N workspaces hidden"
|
|
||||||
fields, no total-vs-visible discrepancy fields. A query naming a
|
|
||||||
node outside §3.2 visibility MUST satisfy the §3.4 response
|
|
||||||
equivalence with a query naming a nonexistent node (fail closed,
|
|
||||||
`rbac-grant-model.md` §3.5 pattern: a decision path that cannot
|
|
||||||
read grant state denies).
|
|
||||||
4. **Response equivalence predicate.** Two responses are equivalent
|
|
||||||
when they carry the identical HTTP status, the identical contract
|
|
||||||
5 §4.2 error code, and byte-identical bodies after normalizing
|
|
||||||
exactly the declared volatile envelope fields — correlation id and
|
|
||||||
response timestamp, and nothing else. The implementing PR declares
|
|
||||||
that volatile-field list in the witness; any additional
|
|
||||||
normalization is a conformance defect. This is contract 5 §4.2's
|
|
||||||
same code/status/shape rule made executable.
|
|
||||||
5. **Live evaluation.** Readability is evaluated per contract 2 §3.5
|
|
||||||
(live rows or transactionally-invalidated cache). Revocation
|
|
||||||
propagates per contract 2 §6: the next roll-up query decided after
|
|
||||||
the revoking transaction commits excludes the revoked scope.
|
|
||||||
|
|
||||||
## 4. Read-only enforcement
|
|
||||||
|
|
||||||
1. **Never a write.** No roll-up path may mutate, claim, order, or
|
|
||||||
gate work in any workspace (§8.2.2). The roll-up ships as a
|
|
||||||
non-mutating query tool (A5 rank 5) — a query surface with no
|
|
||||||
command counterpart.
|
|
||||||
2. **Mechanical enforcement.** The implementing PR executes roll-up
|
|
||||||
database work inside read-only transactions (or an equivalently
|
|
||||||
privilege-restricted path), so a mutation attempt fails at the
|
|
||||||
database boundary, not only by convention.
|
|
||||||
3. **Freshness.** v1 computes the roll-up live from SOT rows at query
|
|
||||||
time. A cache is an implementation option only if it is
|
|
||||||
invalidated in the same transaction as any task, hierarchy, grant,
|
|
||||||
or membership mutation that affects it (each invalidator class
|
|
||||||
witnessed, §6.5), and it is never authoritative (§1.6).
|
|
||||||
|
|
||||||
## 5. Dependencies and phase timing
|
|
||||||
|
|
||||||
1. The roll-up depends on A5 ranks 1–3: contract 1's hierarchy tables
|
|
||||||
(the parent chain), contract 2's evaluator (readability), and the
|
|
||||||
typed Kanban lifecycle (the task state being counted). It ships
|
|
||||||
after them and reads their surfaces; it defines none of them.
|
|
||||||
2. The roll-up query is one tool with one Gateway mapping row under
|
|
||||||
contract 5's regime (request/result/error/audit contracts there);
|
|
||||||
this contract binds its semantics (§2.5 defines the semantic
|
|
||||||
fields the contract 5 §4.1 DTO serializes), not its wire encoding.
|
|
||||||
3. Legacy task rows outside the typed lifecycle are not aggregated;
|
|
||||||
the roll-up begins counting a workspace's tasks when they exist in
|
|
||||||
the typed surface. No roll-up obligation attaches to v1 before
|
|
||||||
ranks 1–3 exist. Both rules are drafting additions disclosed in §7
|
|
||||||
(they trace to no §8 sentence).
|
|
||||||
|
|
||||||
## 6. Verification requirements
|
|
||||||
|
|
||||||
Binding on the implementing PRs. Every witness names, in its
|
|
||||||
implementation, the exact endpoints/tools, tables, and fixtures it
|
|
||||||
exercises. The base fixture seeds two companies; under company A **two
|
|
||||||
estates with distinct, non-identical count profiles**: estate A1 with
|
|
||||||
two platform-projects — P1 holding workspaces W1 and W2, P2 holding
|
|
||||||
workspace W3 — and estate A2 with one platform-project P3 holding one
|
|
||||||
workspace W4, all with known task counts across at least three
|
|
||||||
statuses; under company B one workspace.
|
|
||||||
|
|
||||||
1. **Correctness witnesses:** for a reader holding a direct company-A
|
|
||||||
grant, roll-up totals at every level equal the seeded sums — each
|
|
||||||
workspace, each platform-project, estate A1 and estate A2
|
|
||||||
separately (their distinct profiles asserted distinct), and the
|
|
||||||
company total equal to A1+A2 — keyed by the typed status values,
|
|
||||||
with no double count across the chain. For a reader holding a
|
|
||||||
direct estate-A1 grant, the estate-A1 result equals the A1 sum and
|
|
||||||
a company-A query returns company A with exactly A1's contribution
|
|
||||||
(estate A2 invisible). Each of the three chain grant levels
|
|
||||||
contract 1 §3.1 defines — company, estate, platform-project
|
|
||||||
(below, §6.2) — has an explicit direct-grant case, none simulated
|
|
||||||
by unioning lower access. Workspace-level access has NO direct
|
|
||||||
chain grant (contract 1 §3.1/§3.4 define no workspace grant
|
|
||||||
target) and is covered by the §6.2 membership case.
|
|
||||||
2. **Scope witnesses:** a reader with a direct grant on
|
|
||||||
platform-project P1 only sees exactly P1's subtree counts
|
|
||||||
(W1+W2): a P1 query returns W1+W2; an estate-A1 query returns the
|
|
||||||
estate node with exactly P1's contribution, sibling project P2 and
|
|
||||||
its workspace W3 absent at every depth; a company-A query likewise
|
|
||||||
carries only P1's contribution. An estate-sibling case: a reader
|
|
||||||
with a direct grant on estate A1 only queries company A and
|
|
||||||
receives exactly A1's contribution, estate A2 absent. (Chain
|
|
||||||
grants exist only at company, estate, and platform-project —
|
|
||||||
contract 1 §3.1 — so partial scope among SIBLING WORKSPACES of
|
|
||||||
one project is not constructible by grants and is not witnessed;
|
|
||||||
the constructible partial-scope cases are the project- and
|
|
||||||
estate-sibling ones above.) **Membership locality (§1.4):** a member-only reader queries
|
|
||||||
the workspace directly and receives its counts; the same reader
|
|
||||||
querying the workspace's parent (or any ancestor) receives the
|
|
||||||
§3.4-equivalent nonexistent-node response, and no ancestor
|
|
||||||
response for any other reader changes because of that membership.
|
|
||||||
3. **No-oracle witnesses:** the P1-only reader's estate-A1 response
|
|
||||||
above contains no field disclosing P2's or W3's existence
|
|
||||||
(closed-schema comparison against an estate-A1-granted reader's
|
|
||||||
response: identical field set, differing only in counts and
|
|
||||||
visible nodes). **Partial-scope hidden node:** the P1-only reader
|
|
||||||
— who sees estate A1 and the P1 subtree — queries hidden sibling
|
|
||||||
project P2 by its real id, and separately hidden workspace W3 by
|
|
||||||
its real id; each response satisfies the §3.4 equivalence
|
|
||||||
predicate against the same query naming a nonexistent id, under
|
|
||||||
one fixed request context with the declared volatile-field
|
|
||||||
normalization. **Cross-tenant:** an unauthorized reader naming company B receives
|
|
||||||
a response §3.4-equivalent to naming a nonexistent id. Each
|
|
||||||
equivalence check is executable byte comparison after the declared
|
|
||||||
normalization, not a shape judgment.
|
|
||||||
4. **Empty-vs-hidden witness (ruling):** a reader granted (direct
|
|
||||||
chain grant) on an empty platform-project receives it with zero
|
|
||||||
counts — every status key present at `0` (§2.5); with the grant
|
|
||||||
deleted, the same query returns the §3.4-equivalent
|
|
||||||
nonexistent-node response. An inherited-grant case: a company
|
|
||||||
grant makes an empty descendant platform-project visible with zero
|
|
||||||
counts.
|
|
||||||
5. **Cache-invalidation witnesses (conditional):** bound only if the
|
|
||||||
implementation caches — for EACH invalidator class, prime the
|
|
||||||
cache, commit one mutation of that class, and assert the next
|
|
||||||
query reflects it: a task status change, a task creation, a
|
|
||||||
membership removal (the member-readable workspace disappears from
|
|
||||||
its own node's next query), a workspace reparenting (both old and
|
|
||||||
new parent totals correct), and a grant revocation. A live
|
|
||||||
(cacheless) v1 implementation records that fact and the witnesses
|
|
||||||
bind at the PR that introduces a cache.
|
|
||||||
6. **Mutation witnesses:** the roll-up surface rejects every mutating
|
|
||||||
verb/command; a crafted attempt to issue a write through the
|
|
||||||
roll-up's database path fails at the read-only boundary (§4.2);
|
|
||||||
after any roll-up query, the row diff is empty across BOTH the
|
|
||||||
workspace tables and the hierarchy tables (contract 1 §6.7's
|
|
||||||
both-table zero-write assertion).
|
|
||||||
7. **Closed-schema witness:** the response is asserted field-exact
|
|
||||||
against the §2.5 recursive record at every depth — exactly
|
|
||||||
`id`/`type`/`name`/`totals`/`children` on every node, every typed
|
|
||||||
status present with explicit zeros, `children: []` at every
|
|
||||||
workspace record, the declared ascending-`id` ordering, no
|
|
||||||
wrapper field — and a response carrying any field outside the
|
|
||||||
record at any depth fails the assertion (carve-out boundary,
|
|
||||||
§2.3). The denial envelope is asserted field-exact against
|
|
||||||
contract 5 §4.2's envelope (§2.6).
|
|
||||||
8. **Non-authoritative and never-gate witnesses:** (a) a static
|
|
||||||
production import-graph inventory (hierarchy contract §6.3 style,
|
|
||||||
production code over `apps/` and `packages/`, tests excluded)
|
|
||||||
shows no production module imports the roll-up query module or its
|
|
||||||
result DTO into any SOT write path, any authorization/gating
|
|
||||||
decision path, or any persistence beyond the response lifetime —
|
|
||||||
asserted in both directions (the roll-up module's consumers are
|
|
||||||
enumerated and each is a presentation surface); (b) a behavioral
|
|
||||||
probe: with roll-up output artificially perturbed (test double),
|
|
||||||
no authorization outcome and no work-gating decision anywhere in
|
|
||||||
the fixture suite changes — proving no gate consumes it.
|
|
||||||
9. **Revocation witness:** after revoking the grant that made a
|
|
||||||
subtree readable, the next roll-up query excludes it (contract 2
|
|
||||||
§6.2 bound).
|
|
||||||
|
|
||||||
## 7. Drafting additions (PRD §12.1 disclosure)
|
|
||||||
|
|
||||||
Proposed drafting additions, visible here for ratification, each
|
|
||||||
severable; the aggregation itself, its authorization scope, its
|
|
||||||
read-only nature, and the no-oracle acceptance are traced to
|
|
||||||
`native-kanban-sot.md` §8 and are not additions:
|
|
||||||
|
|
||||||
1. The §3.2 node-visibility rule and the granted-but-empty behavior
|
|
||||||
(the ruling below).
|
|
||||||
2. The §3.3–§3.4 nonexistent-node response equivalence, with its
|
|
||||||
normalized-byte-equality predicate, as the concrete no-oracle
|
|
||||||
mechanism.
|
|
||||||
3. The §4.2 read-only-transaction mechanical enforcement.
|
|
||||||
4. The §4.3 cache option with transactional invalidation and the
|
|
||||||
§6.5 per-invalidator witnesses.
|
|
||||||
5. The §2.5 closed response schema as an amendment boundary.
|
|
||||||
6. The §1.4 membership-locality rule — membership-only readability
|
|
||||||
contributes at the workspace node only (this contract's
|
|
||||||
reconciliation of `native-kanban-sot.md` §8.1.3 "authorized on"
|
|
||||||
with contract 2 §3.1/§7.4's workspace-local membership).
|
|
||||||
7. The §5.3 legacy-row exclusion and the §5.3 pre-rank no-obligation
|
|
||||||
rule.
|
|
||||||
|
|
||||||
## Ruling request
|
|
||||||
|
|
||||||
Ruling requested (one decision): shall a node the reader holds an
|
|
||||||
effective chain role on (direct or inherited, §1.2) but whose
|
|
||||||
aggregation scope is empty appear in the roll-up with zero counts
|
|
||||||
(recommended — it lets the UI show a granted-but-empty subtree
|
|
||||||
honestly) — or, as the alternative, be indistinguishable from a
|
|
||||||
nonexistent node until it contains a readable workspace?
|
|
||||||
Reference in New Issue
Block a user