Implements Spec 095. What changed - Registers 4 Graph resources in the contract registry (plus required subresource template) - Refactors in-scope call sites to resolve Graph paths via the registry (no ad-hoc endpoints for these resources) - Adds/updates regression tests to prevent future drift (missing registry entries and endpoint string reintroduction) - Includes full SpecKit artifacts under specs/095-graph-contracts-registry-completeness/ Validation - Focused tests: - `vendor/bin/sail artisan test --compact tests/Feature/Graph/GraphContractRegistryCoverageSpec095Test.php tests/Feature/SettingsCatalogDefinitionResolverTest.php` Notes - Livewire v4.0+ / Filament v5 compliant (no UI changes). - No new routes/pages; no RBAC model changes. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #114
126 lines
8.5 KiB
Markdown
126 lines
8.5 KiB
Markdown
# Feature Specification: Graph Contracts Registry Completeness
|
||
|
||
**Feature Branch**: `095-graph-contracts-registry-completeness`
|
||
**Created**: 2026-02-15
|
||
**Status**: Draft
|
||
**Input**: Ensure Microsoft Graph resources already used by the product are explicitly registered in the app’s contract registry, and ensure call sites use the registry rather than ad-hoc paths. Add regression tests so these resources can’t silently become “untracked” again.
|
||
|
||
## Spec Scope Fields *(mandatory)*
|
||
|
||
- **Scope**: workspace
|
||
- **Primary Routes**: None (no new user-facing pages or routes)
|
||
- **Data Ownership**: No new persistent records; registry metadata only
|
||
- **RBAC**: No new permissions; behavior must not expand access beyond existing authorization and tenant isolation
|
||
|
||
## Clarifications
|
||
|
||
### Session 2026-02-15
|
||
|
||
- Q: Which enforcement scope do you want for “no freeform Graph paths”? → A: Enforce registry-backed paths only for the 4 specified resources (and the call sites that touch them).
|
||
- Q: What evidence should be required for acceptance? → A: Pest regression tests passing is sufficient evidence.
|
||
- Q: Which code locations should be considered “in scope” for the regression guard? → A: ConfigurationPolicyTemplateResolver, SettingsCatalogDefinitionResolver, SettingsCatalogCategoryResolver, RbacOnboardingService, and RbacHealthService.
|
||
- Q: If we discover additional unregistered Graph resources during implementation, what should we do? → A: Do not expand scope; register only the 4 specified resources (extra findings become a follow-up spec).
|
||
|
||
## User Scenarios & Testing *(mandatory)*
|
||
|
||
### User Story 1 - Drift coverage is complete (Priority: P1)
|
||
|
||
As a maintainer, I need the contract drift check to cover the Graph resources we already depend on, so that operational “drift” detection is trustworthy and doesn’t miss critical resources.
|
||
|
||
**Why this priority**: Drift-check coverage gaps undermine safety and auditability across multiple other workflows.
|
||
|
||
**Independent Test**: A test can assert that the registry explicitly includes the required resources (the same registry enumeration the drift check relies on).
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** the contract registry, **When** it is evaluated for registered resources, **Then** it includes:
|
||
- Configuration Policy Templates
|
||
- Configuration Settings (settings catalog definitions)
|
||
- Configuration Categories
|
||
- RBAC Role Assignments
|
||
2. **Given** the registry entry for configuration policy templates, **When** nested template setting templates are needed, **Then** the registry can represent that subresource using an approved template (including an item identifier placeholder).
|
||
|
||
---
|
||
|
||
### User Story 2 - Graph calls are registry-backed (Priority: P2)
|
||
|
||
As a maintainer, I need Graph calls for these resources to use the contract registry rather than freeform strings, so that endpoints are governed consistently (naming, review, and drift-check alignment).
|
||
|
||
**Why this priority**: Prevents silent expansion of Graph surface area and makes review/audit easier.
|
||
|
||
**Independent Test**: A test can detect reintroduction of hardcoded endpoint substrings in the relevant call sites.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** code paths that fetch settings catalog definitions or categories, **When** they call Graph, **Then** they source the resource path from the contract registry rather than embedding hardcoded endpoint substrings.
|
||
2. **Given** code paths that create/update role assignments, **When** they call Graph, **Then** they source the role-assignments resource path from the contract registry rather than embedding a hardcoded endpoint.
|
||
|
||
---
|
||
|
||
### User Story 3 - Regressions are prevented (Priority: P3)
|
||
|
||
As a maintainer, I need regression tests that fail if these resources become unregistered or if call sites revert to ad-hoc endpoints, so that future refactors cannot silently break governance.
|
||
|
||
**Why this priority**: The risk is gradual “drift” over time; a regression guard is the lowest-cost long-term control.
|
||
|
||
**Independent Test**: A test suite can fail on (a) missing registry entries, and (b) hardcoded endpoint usage in targeted files.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** a future change accidentally removes a required resource from the registry, **When** tests run, **Then** they fail with a clear message identifying which resource is missing.
|
||
2. **Given** a future change introduces a hardcoded endpoint string for one of the covered resources, **When** tests run, **Then** they fail and indicate which endpoint substring was reintroduced.
|
||
|
||
### Edge Cases
|
||
|
||
- Graph permissions or tenant isolation limitations cause the resource to be inaccessible for a given tenant; contract registration must not imply access.
|
||
- The Graph API returns paginated results for list endpoints; registry coverage must not degrade pagination handling.
|
||
- The Graph API evolves (resource moved/renamed/deprecated); contract drift check and tests should reveal mismatch quickly.
|
||
- A subresource path exists for a registered resource but is not represented in the registry; this must be treated as a governance gap.
|
||
|
||
## Requirements *(mandatory)*
|
||
|
||
**Constitution alignment (required):** This feature updates the contract registry for Microsoft Graph resources and adds regression tests to ensure completeness and to prevent ad-hoc expansions of Graph calls.
|
||
|
||
### Functional Requirements
|
||
|
||
- **FR-001**: The system MUST explicitly register the following Graph resources in the contract registry:
|
||
- Configuration Policy Templates
|
||
- Configuration Settings (settings catalog definitions)
|
||
- Configuration Categories
|
||
- RBAC Role Assignments
|
||
- **FR-002**: The system MUST represent the “setting templates” subresource under Configuration Policy Templates as part of the registered contract.
|
||
- **FR-003**: The system MUST ensure that Graph calls for the above resources are sourced from the contract registry (not embedded as freeform endpoint strings in call sites).
|
||
- **FR-003a**: The “no freeform path” enforcement scope MUST be limited to the four specified resources and the known call sites that access them.
|
||
- **FR-004**: The system MUST include regression tests that fail when any of the required resources are not registered.
|
||
- **FR-005**: The system MUST include regression tests that detect reintroduction of ad-hoc endpoint strings in the targeted call sites for these resources.
|
||
- **FR-005a**: The regression guard “targeted call sites” MUST include: ConfigurationPolicyTemplateResolver, SettingsCatalogDefinitionResolver, SettingsCatalogCategoryResolver, RbacOnboardingService, and RbacHealthService.
|
||
- **FR-006**: The implementation scope MUST remain limited to the four specified resources; any additional missing resources discovered during implementation MUST be handled via a follow-up spec.
|
||
|
||
### Registry Identifiers (internal)
|
||
|
||
To make the requirements testable and to avoid ambiguity, the contract registry MUST contain stable internal identifiers for these four resources (under the registry’s “types” section):
|
||
|
||
| Resource | Registry identifier |
|
||
|----------|---------------------|
|
||
| Configuration Policy Templates | `configurationPolicyTemplate` |
|
||
| Configuration Settings (settings catalog definitions) | `settingsCatalogDefinition` |
|
||
| Configuration Categories | `settingsCatalogCategory` |
|
||
| RBAC Role Assignments | `rbacRoleAssignment` |
|
||
|
||
Additionally, the Configuration Policy Template contract MUST include a named subresource for “setting templates” that is templated by the parent template identifier (for example: subresource key `settingTemplates`).
|
||
|
||
### Assumptions
|
||
|
||
- Existing authorization and tenant isolation rules already constrain whether any given tenant can access these resources; contract registration does not add or expand permissions.
|
||
- The contract drift check enumerates registered top-level resources; nested subresources are still registered for governance consistency and reuse.
|
||
|
||
## Success Criteria *(mandatory)*
|
||
|
||
### Measurable Outcomes
|
||
|
||
- **SC-001**: 100% of the specified Graph resources are discoverable from the contract registry.
|
||
- **SC-002**: Regression tests fail within 1 test run if any specified resource becomes unregistered.
|
||
- **SC-003**: Regression tests fail within 1 test run if targeted call sites reintroduce hardcoded endpoint substrings for the specified resources.
|
||
- **SC-004**: Maintainers can demonstrate drift-check coverage for these resources without manual inspection (e.g., via automated verification output or test evidence).
|
||
- **SC-004a**: Acceptance evidence MUST be satisfied by automated tests (Pest) without requiring a live tenant or manual drift-check output.
|