TenantAtlas/.specify/memory/constitution.md
ahmido 3030dd9af2 054-unify-runs-suitewide (#63)
Summary

Kurz: Implementiert Feature 054 — canonical OperationRun-flow, Monitoring UI, dispatch-safety, notifications, dedupe, plus small UX safety clarifications (RBAC group search delegated; Restore group mapping DB-only).
What Changed

Core service: OperationRun lifecycle, dedupe and dispatch helpers — OperationRunService.php.
Model + migration: OperationRun model and migration — OperationRun.php, 2026_01_16_180642_create_operation_runs_table.php.
Notifications: queued + terminal DB notifications (initiator-only) — OperationRunQueued.php, OperationRunCompleted.php.
Monitoring UI: Filament list/detail + Livewire pieces (DB-only render) — OperationRunResource.php and related pages/views.
Start surfaces / Jobs: instrumented start surfaces, job middleware, and job updates to use canonical runs — multiple app/Jobs/* and app/Filament/* updates (see tests for full coverage).
RBAC + Restore UX clarifications: RBAC group search is delegated-Graph-based and disabled without delegated token; Restore group mapping remains DB-only (directory cache) and helper text always visible — TenantResource.php, RestoreRunResource.php.
Specs / Constitution: updated spec & quickstart and added one-line constitution guideline about Graph usage:
spec.md
quickstart.md
constitution.md
Tests & Verification

Unit / Feature tests added/updated for run lifecycle, notifications, idempotency, and UI guards: see tests/Feature/* (notably OperationRunServiceTest, MonitoringOperationsTest, OperationRunNotificationTest, and various Filament feature tests).
Full test run locally: ./vendor/bin/sail artisan test → 587 passed, 5 skipped.
Migrations

Adds create_operation_runs_table migration; run php artisan migrate in staging after review.
Notes / Rationale

Monitoring pages are explicitly DB-only at render time (no Graph calls). Start surfaces enqueue work only and return a “View run” link.
Delegated Graph access is used only for explicit user actions (RBAC group search); restore mapping intentionally uses cached DB data only to avoid render-time Graph calls.
Dispatch wrapper marks runs failed immediately if background dispatch throws synchronously to avoid misleading “queued” states.
Upgrade / Deploy Considerations

Run migrations: ./vendor/bin/sail artisan migrate.
Background workers should be running to process queued jobs (recommended to monitor queue health during rollout).
No secret or token persistence changes.
PR checklist

 Tests updated/added for changed behavior
 Specs updated: 054-unify-runs-suitewide docs + quickstart
 Constitution note added (.specify)
 Pint formatting applied

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #63
2026-01-17 22:25:00 +00:00

100 lines
5.7 KiB
Markdown

<!--
Sync Impact Report
- Version change: 1.2.0 → 1.2.1
- Modified principles:
- Operations / Run Observability Standard (clarify AuditLog vs OperationRun)
- Added sections: None
- Removed sections: None
- Templates requiring updates:
- ✅ .specify/templates/plan-template.md
- ✅ .specify/templates/tasks-template.md
- ✅ .specify/templates/spec-template.md
- Follow-up TODOs:
- TODO(DELETED_STATUS): Keep “deleted” reserved for Feature 900 / Policy Lifecycle.
-->
# TenantPilot Constitution
## Core Principles
### Inventory-first, Snapshots-second
- All modules MUST operate primarily on Inventory as “last observed” state.
- Inventory is the source of truth for what TenantPilot last observed; Microsoft Intune remains the external truth.
- Snapshots/Backups MUST be explicit actions (manual or scheduled) and MUST remain immutable.
### Read/Write Separation by Default
- Analysis, reporting, and monitoring features MUST be read-only by default.
- Any write/change function (restore, remediation, promotion) MUST include preview/dry-run, explicit confirmation, audit logging, and tests.
- High-risk policy types default to `preview-only` restore unless explicitly enabled by a feature spec + tests.
### Single Contract Path to Graph
- All Microsoft Graph calls MUST go through `GraphClientInterface`.
- Object types and endpoints MUST be modeled first in the contract registry (`config/graph_contracts.php`).
- Feature code MUST NOT hardcode “quick endpoints” or bypass contracts.
- Unknown/missing policy types MUST fail safe (preview-only / no Graph calls) rather than guessing endpoints.
### Deterministic Capabilities
- Backup/restore/risk/support flags MUST be derived deterministically from config/contracts via a Capabilities Resolver.
- The resolver output MUST be programmatically testable (snapshot/golden tests) so config changes cannot silently break behavior.
### Tenant Isolation is Non-negotiable
- Every read/write MUST be tenant-scoped.
- Cross-tenant views (MSP/Platform) MUST be explicit, access-checked, and aggregation-based (no ID-based shortcuts).
- Prefer least-privilege roles/scopes; surface warnings when higher privileges are selected.
### Operations / Run Observability Standard
- Every long-running or operationally relevant action MUST be observable, deduplicated, and auditable via Monitoring → Operations.
- An action MUST create/reuse a canonical `OperationRun` and execute asynchronously when any of the following applies:
1. It can take > 2 seconds under normal conditions.
2. It performs remote/external calls (e.g., Microsoft Graph).
3. It is queued or scheduled.
4. It is operationally relevant for troubleshooting/audit (“what ran, who started it, did it succeed, what failed?”).
- Actions that are DB-only and typically complete in < 2 seconds MAY skip `OperationRun`.
- If an action is security-relevant or affects operational behavior (e.g., Ignore policy”), it MUST write an `AuditLog` entry
including actor, tenant, action, target, before/after, and timestamp.
- The `OperationRun` record is the canonical source of truth for Monitoring (status, timestamps, counts, failures),
even if implemented by multiple jobs/steps (“umbrella run”).
- Single-row runs MUST still use consistent counters (e.g., `total=1`, `processed=0|1`) and outcome derived from success/failure.
- Monitoring pages MUST be DB-only at render time (no external calls).
- Start surfaces MUST NOT perform remote work inline; they only: authorize, create/reuse run (dedupe), enqueue work,
confirm + View run”.
- Active-run dedupe MUST be enforced at DB level (partial unique index/constraint for active states).
- Failures MUST be stored as stable reason codes + sanitized messages; never persist secrets/tokens/PII/raw payload dumps
in failures or notifications.
- Graph calls are allowed only via explicit user interaction and only when delegated auth is present; never as a render side-effect (restore group mapping is intentionally DB-only).
- Monitoring Operations is reserved for `OperationRun`-tracked operations.
- Scheduled/queued operations MUST use locks + idempotency (no duplicates).
- Graph throttling and transient failures MUST be handled with backoff + jitter (e.g., 429/503).
### Data Minimization & Safe Logging
- Inventory MUST store only metadata + whitelisted `meta_jsonb`.
- Payload-heavy content belongs in immutable snapshots/backup storage, not Inventory.
- Logs MUST not contain secrets/tokens; monitoring MUST rely on run records + error codes (not log parsing).
### Spec-First Workflow
- For any feature that changes runtime behavior, include or update `specs/<NNN>-<slug>/` with `spec.md`, `plan.md`, `tasks.md`, and `checklists/requirements.md`.
- New work branches from `dev` using `feat/<NNN>-<slug>` (spec + code in the same PR).
## Quality Gates
- Changes MUST be programmatically tested (Pest) and run via targeted `php artisan test ...`.
- Run `./vendor/bin/pint --dirty` before finalizing.
## Governance
### Scope & Compliance
- This constitution applies across the repo. Feature specs may add stricter constraints but not weaker ones.
- Restore semantics changes require: spec update, checklist update (if applicable), and tests proving safety.
### Amendment Procedure
- Propose changes as a PR that updates `.specify/memory/constitution.md`.
- The PR MUST include a short rationale and list of impacted templates/specs.
- Amendments MUST update **Last Amended** date.
### Versioning Policy (SemVer)
- **PATCH**: clarifications/typos/non-semantic refinements.
- **MINOR**: new principle/section or materially expanded guidance.
- **MAJOR**: removing/redefining principles in a backward-incompatible way.
**Version**: 1.2.1 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-01-17