Uh oh!
There was an error while loading. Please reload this page.
Declare hierarchy-security and restore the manager depth grants - #56
Merged
Merged
Conversation
`objectstack.config.ts`, AGENTS.md rule 7 and two docs all said that declaring `requires: ['hierarchy-security']` would fail an open-edition boot. Measured false: it warns, naming the provider package, and every gate stays green. The claim is what forced the three manager depth grants down to `own`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqkTcrxUFci7nqXdbBSe2p
os-warren
marked this pull request as ready for review
September 1, 2026 06:05
Uh oh!
There was an error while loading. Please reload this page.
os-warren pushed a commit
that referenced
this pull request
Sep 1, 2026
Picks up #54 (source defaults to self) and #56 (hierarchy-security). Both touch objects this guard resolves against; no field was renamed or removed, only `default:` flags on select options. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqkTcrxUFci7nqXdbBSe2p
This was referenced Sep 1, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#46
Four places in this repo said declaring
requires: ['hierarchy-security']would fail an open-edition boot. It does not. That belief is what forced the three manager depth grants down toown, so removing it and restoring the grants are one change.Verified on
5dd788b(final commit) with@objectstack/security-enterprisenot installed and nothing added topackage.json.What changed
objectstack.config.ts—requires: ['automation', 'hierarchy-security'], and the comment beside it rewritten. It now quotes the platform's own reason for the check, records the measurement, and says plainly that the warning is the expected state. The "Security posture" comment further down said the scopes "fail closed to owner-only, silently"; that was the same claim in its second half, and it is now the warning-announced behaviour it actually is.src/security/permission-sets.ts—duly_managerreadsunit_and_belowonduly_taskandduly_duty.duly_admingets the task depth by inheritance, not restatement, so the third grant costs no third edit. Both overrides spread the member entry, leavingwriteScope: 'own'inherited rather than retyped.HIERARCHY_SCOPES_DEFERREDand its docblock are gone.Write scopes did not move. A manager reads down and writes nothing but their own — that was never the deferred half.
AGENTS.mdrule 7 — rewritten end to end: a hierarchy scope requires the declaration; omitting it is an author-time hard error that takesvalidate,buildand every test importing the config; declaring it warns and installs nothing; open-edition resolution is owner-only and a local manager view showing only your own rows is the edition, not a bug. It also names the trapdoor next door —orgis not a hierarchy scope, loads with no declaration, and discloses the whole tenant.docs/product/data-model.mdanddocs/deployment/security.md— same claim, same correction. The deployment page's "Two manager grants are currently narrower than this table implies" section is replaced by one describing the declaration and the warning; the model table now shows the manager depth instead of "inherited".Tests
test/security.test.ts. The old stopgap block pinned the compromise in both directions; the new one pins the dependency in both directions:unit_and_below;stack.requiresmust containhierarchy-security— a named failure here instead of an opaque config-load failure across every suite;duly_taskatorg;writeScope: 'own').One deviation, stated
The card asks for a test that no grant anywhere has a write scope wider than
own. Taken literally that is false today:duly_admin.duly_catalog_itemiswriteScope: 'org', deliberately —public_readis read-open but write-owned, so without it an administrator could only edit catalog items they personally created. So it is written as two assertions instead of one:ownbar one allowlisted exception, asserted by equality against that allowlist, so adding a second exception is a deliberate act rather than a silent pass;The second one earns its place: with the capability declared, the platform check accepts a hierarchy scope on either axis. It does not distinguish read from write. Nothing but this test stops a write depth from loading now.
Ablations
Four legs, each mutation confirmed on disk before measuring, each restored by an
EXIT/INT/TERMtrap. Tests resolve app code by relative path through vitest's transform — no packageexports→distboundary and no vitest alias (there is no vitest config file) — so no rebuild leg applies here.hierarchy-securityfromrequiresvalidatereddefineStack hierarchy-scope capability validation failed (3 issues), naming all three grants —duly_admin.duly_taskamong them, which also proves the inherited grant is realduly_manager.duly_task.writeScope: 'org'validategreenexpected { …(3) } to deeply equal { Object (duly_admin.duly_catalog_item) }. Config loaded —orgneeds no declaration, which is the pointduly_manager.duly_task.writeScope: 'unit_and_below'duly_manager.duly_task writes by hierarchy depth: expected [ 'own_and_reports', 'unit', …(1) ] to not include 'unit_and_below'. Config still loadedduly_manager.duly_task.readScopeback to'own'One honesty note on the on-disk confirmation: the injected-marker count (
MUTANT, want 1) was correct on every leg and is what proves each mutation landed. The paired removed-anchor count was mis-anchored — its pattern also matched the untouchedduly_dutyoverride — so it read 2/1/1 instead of 0. The marker count and the assertion output naming the mutated value are the evidence; that counter is not.Gates
All four green on
5dd788b, run under the container's shared verify lock:The warning is the acceptance criterion, not a leftover.
File-surface note
One file beyond the declared surface:
src/security/index.ts, which re-exportedHIERARCHY_SCOPES_DEFERRED. Deleting the constant without it is a compile error, so it is the mechanical completion of the card's own step 2 rather than new scope — a four-line export list losing one line. No sibling card in this round touches it (#51 datasets, #50duty.object.ts, #27 global actions).src/objects/duty.object.tswas not touched.Found outside the file surface — reported, not edited
docs/roadmap.md(M2 bullet) says an open-edition checkout "correctly shows owner-only rows". That half is true and stays true. It does not repeat the falsified claim, so it is left alone.Generated by Claude Code