Restore shared place capability and authority rules - #23
Conversation
Add one shared server-side capability resolver for geographic place authority. Block, hood, and colony authority now use that resolver. Historically verified rules: - Leader at the exact place: canAdmin + canManageAccess - Deputy at the exact place: canAdmin only - Leader or Deputy at a descendant: canManageAccess only - Parent, sibling, and unrelated places: deny Owner-approved modern policy: - ColonyRepresentative receives canManageAccess at every geographic colony, hood, and block place. It does not receive canAdmin.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📜 Recent review details⏰ Context from checks skipped due to timeout. (1)
🧰 Additional context used📓 Path-based instructions (3)Mandatory engineering review policy:⚙️ CodeRabbit configuration file Files:
**API (`api/`): single quotes** — `'like this'`. Exception: SQL query strings.📄 CodeRabbit inference engine (CLAUDE.md) Files:
**Blank line (newline) at end of every file** (`eol-last`).📄 CodeRabbit inference engine (CLAUDE.md) Files:
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds ChangesPlace capability authorization
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to The PR centralizes place authority rules and narrows inherited update permissions while preserving access-management behavior; no actionable merge-blocking risk remains after normal checks and review. Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors)
✅ Passed checks (5 passed)
Full details: Touched Files Lint CleanExplanation The touched-file lint check fails. Using the repository's ESLint configuration with ESLint 7.32.0 and Resolution Make all six changed files lint-clean under Full details: No Repository DebrisExplanation PASS. The PR diff contains only six expected TypeScript source/test files under Full details: Risky Writes Are SafeExplanation The PR changes Resolution Return immediately after the authorization failure in Full details: Regression CoverageExplanation Focused regression coverage is present. The PR adds Full details: Pr Scope Remains CoherentExplanation PASS: The change set is coherent with the stated capability-resolver purpose. The diff contains only the three place services, the resolver, its focused spec, and the services barrel export. The service edits replace the existing Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🟢 Approval recommended
The authorization behavior is consolidated and covered by a dedicated test suite, and the only feedback is a minor documentation clarification in the new resolver.
Pull request overview
This PR centralizes geographic place authority decisions (colony → hood → block) into a single server-side capability resolver, then updates the colony/hood/block services to use that shared resolver for canAdmin and canManageAccess checks, restoring the historically verified access boundary (admin does not inherit downward; access-rights can).
Changes:
- Added
PlaceCapabilityServiceto resolve{ canAdmin, canManageAccess }consistently for geographic places. - Refactored
BlockService,HoodService, andColonyServiceto delegatecanAdmin/canManageAccessto the shared resolver. - Added a focused Jest spec suite covering historical rules, the ColonyRepresentative policy, and malformed-tree fail-closed behavior.
File summaries
| File | Description |
|---|---|
| api/src/services/place/place-capability.service.ts | New shared capability resolver implementing the restored authority rules (plus ColonyRepresentative policy). |
| api/src/services/place/place-capability.service.spec.ts | Unit tests validating capability outcomes across roles, tree positions, and malformed inputs. |
| api/src/services/index.ts | Exports the new PlaceCapabilityService from the services barrel. |
| api/src/services/hood/hood.service.ts | Replaces inline hood authority rules with calls to PlaceCapabilityService.resolve(). |
| api/src/services/colony/colony.service.ts | Replaces inline colony authority rules with calls to PlaceCapabilityService.resolve(). |
| api/src/services/block/block.service.ts | Replaces inline block authority rules with calls to PlaceCapabilityService.resolve(). |
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| * Roles that carry both capabilities at every place, with no place scoping. These stand in | ||
| * for classic Cybertown's global grant, which was an access check against a single | ||
| * city-wide object rather than against the place being viewed. |
Summary
PLACE-1 adds one shared server-side capability resolver for geographic place authority.
Block, hood, and colony authority now use that shared resolver instead of three separate
inline rule sets. The server remains the authority for every capability decision.
Resolved capabilities:
canAdmincanManageAccessHistorically verified restoration
The restoration was verified against:
The verified historical rule:
Resulting matrix — HISTORICALLY VERIFIED RESTORATION:
canAdmincanManageAccessAdmin keeps global geographic scope with
canAdmin = trueandcanManageAccess = true.Owner-approved modern policy
This section is not a historical claim.
ColonyRepresentative effect
At every geographic place (colony, hood, block):
canAdmin = falsecanManageAccess = trueAt non-geographic places:
canAdmin = falsecanManageAccess = falseConcretely, ColonyRepresentative:
This is not full Admin authority.
Security change
Current fork behavior was too broad.
Before PLACE-1:
After PLACE-1:
This restores the historical boundary. Update authority no longer leaks down the tree.
Tests
Eight Knex loader suite failures are pre-existing baseline debt on this repository. They
are unrelated to this change and were failing before it. This PR does not claim the
entire repository test suite is green.
Fresh QA
Fresh independent security QA passed the exact committed source bytes.
Final file SHA-256 hashes:
The committed bytes are identical to the QA-tested bytes.
Tracker
Related: Cyber-Town-Next-Gen/ctr-restoration#32 (PLACE-1), issue #3 (ColonyRepresentative policy).