Skip to content

Restore shared place capability and authority rules - #23

Merged
DJAscendance merged 1 commit into
masterfrom
restore/place-capability-authority
Sep 1, 2026
Merged

Restore shared place capability and authority rules#23
DJAscendance merged 1 commit into
masterfrom
restore/place-capability-authority

Conversation

@DJAscendance

Copy link
Copy Markdown
Owner

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:

capability meaning
canAdmin Update authority (edit the place, save map backgrounds)
canManageAccess Access Rights authority (grant and remove local offices)

Historically verified restoration

The restoration was verified against:

  • the running historical Cybertown VM
  • historical templates
  • historical access-rights configuration
  • historical CGI behavior
  • historical role and place data

The verified historical rule:

Update is exact-place only.
Access Rights can inherit down the geographic tree.
Authority does not inherit upward.
Authority does not move sideways.

Resulting matrix — HISTORICALLY VERIFIED RESTORATION:

holder position canAdmin canManageAccess
Leader at the exact place true true
Deputy at the exact place true false
Leader or Deputy at a descendant place false true
Parent place deny deny
Sibling place deny deny
Unrelated place deny deny

Admin keeps global geographic scope with canAdmin = true and canManageAccess = true.


Owner-approved modern policy

This section is not a historical claim.

ColonyRepresentative is not treated as a historical global administrator.

Ryan approved ColonyRepresentative as a global colony-level Access Rights role.

It receives canManageAccess across colony, neighborhood, and block places.

It does not receive canAdmin through this policy.

This allows the existing colony Access Rights path to assign ColonyLeader and ColonyDeputy.

This policy is intentionally separate from the historically verified local office rules.

ColonyRepresentative effect

At every geographic place (colony, hood, block):

  • canAdmin = false
  • canManageAccess = true

At non-geographic places:

  • canAdmin = false
  • canManageAccess = false

Concretely, ColonyRepresentative:

  • can manage Access Rights at every colony
  • can manage Access Rights at descendant hoods and blocks
  • cannot use Update authority by role alone
  • cannot save map backgrounds by role alone
  • can assign ColonyLeader through the existing colony Access Rights endpoint
  • can assign ColonyDeputy through the existing colony Access Rights endpoint

This is not full Admin authority.


Security change

Current fork behavior was too broad.

Before PLACE-1:

Colony and Hood office holders could inherit canAdmin into descendants.

After PLACE-1:

ancestor offices inherit Access Rights only

This restores the historical boundary. Update authority no longer leaks down the tree.


Tests

PLACE-1 focused tests: 50 passed
affected passing tests: 211 passed
TypeScript: PASS
production TypeScript: PASS
API build: PASS
lint delta: 0 new errors, 0 new warnings
git diff --check: PASS

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:

e22fcc7e5129d1b42194ce60cf71706d13283c2554f6b60f368d59f173df7b2a  api/src/services/block/block.service.ts
7f5ddbaf4c08ac2e4fd39fc717f42904be2466ab43d691949f9c0d53c250b07d  api/src/services/colony/colony.service.ts
803cc84f993c2c8c228914e45a8e8e80c761996062f10706af22ab68edf5592d  api/src/services/hood/hood.service.ts
996c27cac9aa4aac93ae639d95e5a74eba5ac485256e4470bfc6666e0fa0996b  api/src/services/index.ts
a206dc338b8ca7774974dc6a96ce269f4619a1876cc6ebc10a9c0475521953f2  api/src/services/place/place-capability.service.spec.ts
db2b69582ff645b592764415867c5dc4d0155fe37c3b6937321f03af76b72f2c  api/src/services/place/place-capability.service.ts

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).

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.
Copilot AI lite review requested due to automatic review settings September 1, 2026 01:29
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: 0621c681-f729-43ed-a61d-e8364855a359

📥 Commits

Reviewing files that changed from the base of the PR and between a3110c5 and 4b7a364.

📒 Files selected for processing (6)
  • api/src/services/block/block.service.ts
  • api/src/services/colony/colony.service.ts
  • api/src/services/hood/hood.service.ts
  • api/src/services/index.ts
  • api/src/services/place/place-capability.service.spec.ts
  • api/src/services/place/place-capability.service.ts

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)
  • GitHub Check: copilot-pull-request-reviewer
🧰 Additional context used
📓 Path-based instructions (3)
Mandatory engineering review policy:

⚙️ CodeRabbit configuration file

Files:

  • api/src/services/index.ts
  • api/src/services/place/place-capability.service.ts
  • api/src/services/place/place-capability.service.spec.ts
  • api/src/services/block/block.service.ts
  • api/src/services/colony/colony.service.ts
  • api/src/services/hood/hood.service.ts
**API (`api/`): single quotes** — `'like this'`. Exception: SQL query strings.

📄 CodeRabbit inference engine (CLAUDE.md)

Files:

  • api/src/services/index.ts
  • api/src/services/place/place-capability.service.ts
  • api/src/services/place/place-capability.service.spec.ts
  • api/src/services/block/block.service.ts
  • api/src/services/colony/colony.service.ts
  • api/src/services/hood/hood.service.ts
**Blank line (newline) at end of every file** (`eol-last`).

📄 CodeRabbit inference engine (CLAUDE.md)

Files:

  • api/src/services/index.ts
  • api/src/services/place/place-capability.service.ts
  • api/src/services/place/place-capability.service.spec.ts
  • api/src/services/block/block.service.ts
  • api/src/services/colony/colony.service.ts
  • api/src/services/hood/hood.service.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added centralized permission handling across colonies, hoods, and blocks.
    • Standardized administration and access-management capabilities based on roles and place hierarchy.
    • Added safeguards that deny access for invalid or unsupported place assignments.
  • Bug Fixes

    • Corrected permission inheritance so authority flows only to eligible child places and does not extend sideways or upward.
  • Tests

    • Added comprehensive coverage for role-based permissions, hierarchy rules, malformed inputs, and edge cases.

Walkthrough

Adds PlaceCapabilityService to centralize role and place-hierarchy authorization. Colony, hood, and block services delegate capability checks to it. New tests cover local roles, inheritance, global roles, invalid inputs, and malformed hierarchies.

Changes

Place capability authorization

Layer / File(s) Summary
Capability resolution rules
api/src/services/place/place-capability.service.ts
Adds PlaceCapabilities, scoped place types, role mappings, validation, ancestor traversal, and resolve logic for administrative and access-management capabilities.
Service authorization delegation
api/src/services/block/block.service.ts, api/src/services/colony/colony.service.ts, api/src/services/hood/hood.service.ts, api/src/services/index.ts
Injects PlaceCapabilityService into the place services and delegates canAdmin and canManageAccess checks to resolve. Exports the new service.
Capability behavior validation
api/src/services/place/place-capability.service.spec.ts
Adds mocked repository fixtures and tests for role behavior, hierarchy inheritance, global roles, invalid input, and malformed place relationships.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 4b7a3

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 failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors)

Check name Status Explanation Resolution
Touched Files Lint Clean ❌ Error The touched-file lint check fails. Using the repository's ESLint configuration with ESLint 7.32.0 and @typescript-eslint 5.13.0 reports 25 warnings in three changed files: block.service.ts has 7, `c… Make all six changed files lint-clean under api/.eslintrc.json. Remove the unused Member and includes imports, and replace or otherwise resolve every reported Unexpected any in the touched block, colony, and hood service files. Re-r…
Risky Writes Are Safe ❌ Error The PR changes canAdmin so a ColonyRepresentative or an ancestor office holder is denied at a block. BlockController.postLocations still sends the denial response but does not return. It then re… Return immediately after the authorization failure in BlockController.postLocations. Perform the reset and all location updates in one database transaction, await every write, and roll back on any failure. Send a success response only aft…
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the shared capability resolver and authority-rule restoration implemented in the changeset.
Description check ✅ Passed The description directly explains the shared resolver, capability rules, ColonyRepresentative policy, security change, and reported validation results.
No Repository Debris ✅ Passed PASS. The PR diff contains only six expected TypeScript source/test files under api/src/services. The two added files are the documented capability service and its Jest spec. The commit adds no bina…
Regression Coverage ✅ Passed Focused regression coverage is present. The PR adds api/src/services/place/place-capability.service.spec.ts with assertions for exact-place leader/deputy authority, descendant access-only inheritanc…
Pr Scope Remains Coherent ✅ Passed 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 servi…
Full details: Touched Files Lint Clean

Explanation

The touched-file lint check fails. Using the repository's ESLint configuration with ESLint 7.32.0 and @typescript-eslint 5.13.0 reports 25 warnings in three changed files: block.service.ts has 7, colony.service.ts has 8, and hood.service.ts has 7. The warnings are @typescript-eslint/no-unused-vars and @typescript-eslint/no-explicit-any. The new service, spec, and barrel files report no diagnostics. The PR description claims zero new lint warnings, but the changed files still emit warnings. The configured CI workflow does not run lint.

Resolution

Make all six changed files lint-clean under api/.eslintrc.json. Remove the unused Member and includes imports, and replace or otherwise resolve every reported Unexpected any in the touched block, colony, and hood service files. Re-run the exact API lint command and require zero errors and zero warnings.

Full details: No Repository Debris

Explanation

PASS. The PR diff contains only six expected TypeScript source/test files under api/src/services. The two added files are the documented capability service and its Jest spec. The commit adds no binary files or artifact-like paths, and the working tree has no untracked files. git diff --check passes. A scan of all 848 added lines found no credentials, secrets, local paths, payload blobs, logs, traces, dumps, screenshots, or temporary-file markers.

Full details: Risky Writes Are Safe

Explanation

The PR changes canAdmin so a ColonyRepresentative or an ancestor office holder is denied at a block. BlockController.postLocations still sends the denial response but does not return. It then resets all block locations and enables them one by one. Therefore, a newly denied caller can still mutate location availability. If a later database write fails, the reset and earlier writes remain committed, leaving a partial update. The handler can also send a denial before the mutation completes and then attempts a success response. The route is live at POST /api/block/:id/locations, and the new resolver tests explicitly establish canAdmin: false for ColonyRepresentative at a block.

Resolution

Return immediately after the authorization failure in BlockController.postLocations. Perform the reset and all location updates in one database transaction, await every write, and roll back on any failure. Send a success response only after the transaction commits. Add a regression test that uses a newly denied ancestor or ColonyRepresentative role and verifies that no mutation occurs, plus a failure test that verifies rollback after a location write fails.

Full details: Regression Coverage

Explanation

Focused regression coverage is present. The PR adds api/src/services/place/place-capability.service.spec.ts with assertions for exact-place leader/deputy authority, descendant access-only inheritance, parent and sibling denial, global Admin, ColonyRepresentative, and malformed input. Jest discovers **/*.spec.ts, and the changed Block, Hood, and Colony methods all delegate to the tested PlaceCapabilityService.resolve behavior. The custom check fails only when focused coverage is absent.

Full details: Pr Scope Remains Coherent

Explanation

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 canAdmin and canManageAccess checks with resolver calls. The new production logic and tests cover the same authorization behavior. No unrelated files or formatting-only churn are present, and git diff --check passes.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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 PlaceCapabilityService to resolve { canAdmin, canManageAccess } consistently for geographic places.
  • Refactored BlockService, HoodService, and ColonyService to delegate canAdmin / canManageAccess to 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.

Comment on lines +44 to +46
* 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.
@DJAscendance
DJAscendance merged commit 61b5c55 into master Sep 1, 2026
3 checks passed
@DJAscendance
DJAscendance deleted the restore/place-capability-authority branch September 1, 2026 02:31
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.

2 participants