Propagation-based state inheritance for namespaces
## Overview This epic tracks the implementation of switching from **lookup-based to propagation-based state inheritance** for GitLab's namespace hierarchy (Organization > Group > Subgroup > Project), as described in [ADR 003: State Propagation Model](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/group_and_project_operations_and_state_management/decisions/003_state_propagation_model/) and [MR !19153](https://gitlab.com/gitlab-com/content-sites/handbook/-/merge_requests/19153). ### Problem The current lookup-based approach determines effective state by traversing up the ancestor hierarchy at read time. This causes: - Read-time query overhead on every state check - Inconsistent state inference across descendants - No clear propagation rules through the hierarchy - Caching complexity to mitigate read performance ### Solution Propagate states (`active`, `archived`, `deletion_scheduled`) to all descendants when set on a namespace, enabling fast reads via simple column comparisons without ancestor traversal. ### DRI @aakriti.gupta --- ## Implementation Outline ## Key Technical Decisions ## References - [ADR 003: State Propagation Model MR !19153](https://gitlab.com/gitlab-com/content-sites/handbook/-/merge_requests/19153) - [ADR 001: Unified State Management](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/group_and_project_operations_and_state_management/decisions/001_unified_state_management/) - [ADR 006: State Preservation](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/group_and_project_operations_and_state_management/decisions/006_state_preservation/) - [Tree Iterator Documentation](https://docs.gitlab.com/development/database/poc_tree_iterator/) - [Transactional Outbox Pattern](https://microservices.io/patterns/data/transactional-outbox.html) <!-- STATUS NOTE START --> ## Status 2026-08-13 :clock1: **total hours spent this week by all contributors**: 10h _(Estimate: in line with last week's 10h. Team was partially OOO; the week's focus was landing the core worker and opening the next follow-ups.)_ :tada: **achievements**: - **Core propagation worker merged — the epic's main bottleneck is cleared:** [!242220](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/242220) (`Namespaces::StatePropagationWorker`, [#599298](https://gitlab.com/gitlab-org/gitlab/-/work_items/599298)) merged. This was the single blocker every remaining Phase 3–6 issue was funnelling through last week, so its landing unblocks the rest of the epic. - **State-preservation integration opened for review:** [!243865](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/243865) ([#599299](https://gitlab.com/gitlab-org/gitlab/-/work_items/599299)) extends the worker to preserve a descendant's previous state so it can be restored if a parent operation is cancelled ([ADR 006](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/group_and_project_operations_and_state_management/decisions/006_state_preservation/)) — the first follow-up to start now that the worker is in. - **Reconciliation cron worker queued behind the core worker:** [!242221](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/242221) ([#599300](https://gitlab.com/gitlab-org/gitlab/-/work_items/599300)) is ready to progress now that its dependency has merged; it catches lost or stalled propagation jobs. :issue-blocked: **blockers**: - The Phase 4 outbox callback [!247075](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/247075) ([#599305](https://gitlab.com/gitlab-org/gitlab/-/work_items/599305)) was **closed** rather than merged and needs a replacement MR to keep Phase 4 moving. Deferring domain events/webhooks ([#599308](https://gitlab.com/gitlab-org/gitlab/-/work_items/599308)) remains blocked on that callback landing. :arrow_forward: **next**: - Land the state-preservation integration [!243865](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/243865) and the reconciliation cron worker [!242221](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/242221) now that the core worker has merged. - Re-open/replace the Phase 4 after_transition callback [#599305](https://gitlab.com/gitlab-org/gitlab/-/work_items/599305), then proceed to event/webhook deferral [#599308](https://gitlab.com/gitlab-org/gitlab/-/work_items/599308). - Resume [Phase 6](https://gitlab.com/groups/gitlab-org/-/work_items/21925) observability work — metrics [#599314](https://gitlab.com/gitlab-org/gitlab/-/work_items/599314) and structured logging [#599315](https://gitlab.com/gitlab-org/gitlab/-/work_items/599315). _Copied from https://gitlab.com/groups/gitlab-org/-/epics/21607#note_3680084129_ <!-- STATUS NOTE END -->
epic