ADR-0014 -- Phase 6 retrospective: Track A cohort handover trajectory
Status: Accepted. Date: 2026-05-23. Deciders: Jhoelperaltap (Owner), Tech Lead (this codebase), Counterbook adopter Tech Lead (parallel session, Owner-relayed). Supersedes: None. Superseded by: None. Related: ADR-0013 (Three-mode read/write semantics) -- core Phase 6 architectural foundation; Counterbook ADR-0015 (downstream catalog of 13 findings driving Phase 6 trajectory); Counterbook ADR-0025 / 0026 / 0027 (downstream governance ADRs validating Pattern Cluster F adopter ADR-driven governance pattern).
Context
Phase 6 was TenantShield's first phase informed empirically by Track A
adopter feedback. Counterbook (Owner's parallel SaaS contable project)
served as the inaugural reference adopter, integrating TenantShield
v0.5.0a0 in production-style work and surfacing 13 architectural
findings during Sprints 0-4. The findings were catalogued in
Counterbook's ADR-0015 and handed back to TenantShield for upstream
resolution.
Phase 6 ran for 7 days (2026-05-17 → 2026-05-23) and produced
5 incremental releases (v0.5.1-alpha → v0.5.4-alpha)
plus the Phase 6 root tag v0.6.0-alpha. Across the phase,
4 Counterbook validation cycles (#007-KG003, #008-CTA-AUDIT,
009-AUTO-PROPAGATE, #010 minimal pin bump) empirically ratified the
upstream architectural extensions. By Day 6 closure, all 13 ADR-0015 findings were cleared (12 RESOLVED via implementation + 1 PRE-RESOLVED via Rule 70 archaeology).
This ADR consolidates the Phase 6 retrospective: the trajectory summary, the 7 Pattern Clusters that crystallized empirically during the phase, the 5 Rules (74-78) ratified as project conventions, the reference adopter acknowledgment, and the lessons-learned for future phases that scale beyond single-adopter validation.
Trajectory summary
Five incremental releases on a 7-day cadence, each tied to a specific Counterbook validation cycle:
| Day | Release | Architectural work | Counterbook cycle | Finding(s) cleared |
|---|---|---|---|---|
| 1 (2026-05-17) | v0.5.1-alpha |
D-MEM.0 + ADR-0013 + D-USU.0 (_unsafe_unscoped) |
#007-KG003 | #10 (HIGH) |
| 2-3 (2026-05-23) | v0.5.2-alpha |
D-MEM.1 + CI recovery + D-CTA.0 (cross-tenant audit) | #008-CTA-AUDIT | #1 (SOC2 BLOCKER) |
| 4 (2026-05-23) | v0.5.3-alpha |
D-MEM.2 + D-VAL.0 SKIP + D-DX.0 + D-AUTO.0 (FK auto-propagate) | #009-AUTO-PROPAGATE | #2 + #5 + #6 + #11 |
| 5 (2026-05-23) | v0.5.4-alpha |
D-MEM.3 + D-PERF.0 + D-PY314.0 + D-DOCS.0 | #010 (saturation) | #7 + #8 + #9 + #12 + #13 |
| 6 (2026-05-23) | (NO TAG, consolidated) | D-MEM.4 + D-NEST.0 SKIP + D-MIG.0 + D-ADM.0 | (deferred to Day 7) | #3 + #4 |
| 7 (2026-05-23) | v0.6.0-alpha (this) |
D-MEM.5 + D-DIST.0 + Item-26 defer + ADR-0014 + CHANGELOG | (anticipated #011 post-tag) | -- closure -- |
The "Day" numbering refers to architectural work cadence, not calendar days; Days 2-7 all closed on 2026-05-23 because the trajectory ran faster than the planned 7-day calendar window.
The 7 Pattern Clusters
Empirically crystallized across the phase. Each cluster emerged from multiple specific instances; the abstraction is documented here for future-phase reference and adopter guidance.
Cluster A -- "3-mode read/write semantics + Triple-layer defense"
Foundation: ADR-0013 codified Model.objects (mode 1) + _unscoped
(mode 2) + _unsafe_unscoped (mode 3) as the canonical access
contract for @tenant_aware models. Empirically refined into a
triple-layer defense model (see docs/concepts/security-posture.md):
- Layer 1: Manager scope filtering (passive).
- Layer 2:
audit_cross_tenant_attempts=True(soft-audit, D-CTA.0). - Layer 3:
auto_propagate_from_parent_fk=True(HARD REJECT, D-AUTO.0; empirically surfaced by Counterbook #009 -- NOT in ADR-0013 spec).
The Counterbook #009 validation discovered that D-AUTO.0 + the existing validator chain delivers a HARD REJECT on cross-tenant FK attempts before the INSERT executes -- a stronger guarantee than ADR-0013 anticipated. The triple-layer composition is the empirically-validated security posture documented in Phase 6 docs.
Cluster B -- "Silent → Observable"
Findings #1 (SOC2 BLOCKER) + #5 (startup validation) + #8
(pre_save performance overhead) shared the theme that enterprise
compliance posture requires observable behaviour, not silent
correctness. Pre-Phase-6 v0.5.0-alpha was correct (cross-tenant
writes returned 0 rows) but silent (no audit, no exception). Phase 6
elevated each silent failure mode into an observable signal: audit
events (D-CTA.0), startup checks (#5 PRE-RESOLVED via Phase 2
infrastructure E001..W002), benchmark pins (D-PERF.0). The cluster's
operational consequence: SIEM tooling can now detect what was
previously invisible.
Cluster C -- "DX sugar over primitives"
Findings #2 + #6 + #11 shared the theme that adopter ergonomics is not the same as architectural correctness. The Phase 5 API was correct; Phase 6 D-DX.0 + D-AUTO.0 layered ergonomic surfaces on top without sacrificing safety:
MissingTenantContextErrornow includes a canonical pattern hint.tenant_scope_for_company(company)takes a Django instance directly (Counterbook adopted in 106 callsites).@tenant_aware(auto_propagate_from_parent_fk=True)eliminates thechild.company = parent.companyboilerplate pattern.
Cluster D -- "Django integration polish"
Findings #3 + #4 + #7 + #9 shared the theme of first-class Django ecosystem citizenship vs parallel system. Phase 6 D-MIG.0 + D-ADM.0 + D-DOCS.0 closed the gaps:
tenantshield.adapters.django.migrationsexposes inspection helpers for@tenant_awaremodel metadata (Finding #3).TenantAwareAdminmixin auto-includes the tenant filter in Django admin (Finding #4).select_for_updateinteraction + nestedtenant_scopesemantics +_unscopedcontract documented in concept docs (Findings #7 + #9 + #12 + #13).
Cluster E -- "Cross-session coordination protocol"
Phase 6 operated under a tri-session model:
- TenantShield Tech Lead session (this codebase's planning context).
- Counterbook Tech Lead session (parallel adopter's planning).
- Executor session (this codebase's IC work).
The Owner served as coordinator, relaying state between sessions. 4 consecutive validation cycles operated without friction; the protocol is empirically reproducible. Documented as Item-25 in Phase 6 backlog and codified here:
- Upstream emits an architectural extension (e.g., D-USU.0).
- Tag pushed, release notes prepared.
- Owner relays trigger message to adopter session.
- Adopter executes integration (per their ADR-driven governance).
- Adopter approves with empirical validation report.
- Owner relays approval back upstream.
- Upstream proceeds to next architectural extension.
The model scales for small-N cohorts. Track B / C onboarding may surface coordination protocol limits and motivate Phase 7 work.
Cluster F -- "Adopter ADR-driven governance per API surface"
(Note: not a separate enumerated cluster in the Phase 6 emergence
order; folded into Cluster C / E in documentation -- listed here for
completeness as the Counterbook ADR-0025 / 0026 / 0027 pattern.)
Adopter codebases SHOULD maintain local ADRs that codify usage
policy per TenantShield API surface. Counterbook's ADR-0025
(_unsafe_unscoped whitelist) + ADR-0026 (audit scope policy) +
ADR-0027 (auto-propagation governance) became the canonical example.
Documented in docs/concepts/adopter-governance.md (Phase 6 Day
5). Empirically validated across 4 cycles.
Cluster G -- "Adopter empirical exploration reveals stronger guarantees than spec" + saturation indicator
The three D-* tareas that shipped architectural extensions (D-USU.0, D-CTA.0, D-AUTO.0) all surfaced empirical value beyond the spec:
- D-USU.0 + Counterbook #007: >10x bulk-create perf gain (architectural unblock + perf gain combined value).
- D-CTA.0 + Counterbook #008: auditor-grade
caller_stack_framesforensics (SOC2/PCI-DSS posture stronger than spec described). - D-AUTO.0 + Counterbook #009: HARD REJECT security posture (NOT in ADR-0013 spec).
Counterbook #010 (the v0.5.4-alpha pin bump) surfaced ZERO new architectural insights -- a saturation indicator. The 3-cycle pattern of "insights beyond spec" gave way to a single-commit pin bump with no new architectural learning. Empirical lesson: future multi-cohort onboarding can use the cycle count of "no new insights" as an API stability metric per cohort.
Cluster H -- "Empirical pragmatism trumps rigid procedural ideals"
Two empirical observations stacked into a single cluster:
-
Day 5 (D-PERF.0): empirical archaeology revealed Django signals are per-sender; non-tenant-aware models incur zero handler overhead. The expected optimization (early-return shortcut) was unnecessary because the existing architecture (signal dispatch +
_signal_bypass_var) was already efficient. Pattern: measure empirical baseline BEFORE designing an optimization. -
Day 6 (D-MIG.0 + D-ADM.0): the spec called for two atomic commits; the empirical reality was that the two findings shared
__init__.pyexports that couldn't be cleanly split without artificial intermediate states. Tech Lead acknowledged Option β (combined commit) as valid. Pattern: commit atomicity should respect file-level cohesion when forced splits create artifacts.
The umbrella theme: rigid procedural ideals (single-finding per-commit, optimize-before-measuring) yield to empirical pragmatism when the procedural cost exceeds the architectural value.
Rules 74-78 ratified
Rules 74-78 are added to the project rule catalog (Rules 1-73 from prior phases unchanged). Each derives from a specific Pattern Cluster crystallization.
-
Rule 74 -- Per-operation aggregation in dual-dispatch audit emission. When an audit emit fires on a bulk operation (N rows), emit ONE event with N PKs in the payload, NOT N events. Derived from D-CTA.0 empirical adoption (Counterbook #008).
-
Rule 75 -- Inverse pinning test convention. Behavioural tests for opt-in audit / detection APIs MUST validate BOTH directions: emission-when-violation AND silence-when-legitimate. Derived from Counterbook IC architectural judgment during #008 integration.
-
Rule 76 -- Adopter ADR-driven governance per API surface. Each TenantShield opt-in primitive (
_unsafe_unscoped,audit_cross_tenant_attempts,auto_propagate_from_parent_fk) SHOULD be paired with a local adopter ADR codifying scope policy, whitelist / blacklist, test convention, and compliance hook. Derived from Counterbook ADR-0025 / 0026 / 0027 pattern. -
Rule 77 -- Cohort handover surfaces architectural value beyond spec author capacity. Spec architectural extensions as "minimum guaranteed contract" with documentation hooks for empirical enrichment from adopter integration. Derived from Pattern Cluster G across 3 consecutive validation cycles.
-
Rule 78 -- Empirical baseline + pragmatic atomicity. (a) Architectural performance work MUST establish empirical baseline before designing an optimization. (b) Commit atomicity should respect file-level cohesion when interleaved changes prevent a clean split. Derived from Pattern Cluster H (Day 5 archaeology + Day 6 combined commit).
Reference adopter acknowledgment
Counterbook (Owner's parallel SaaS contable project, integrating
TenantShield since v0.5.0a0) served as Phase 6's reference
adopter. Counterbook's contributions across the phase:
- 13 findings catalogued (ADR-0015), driving the entire Phase 6 trajectory.
- 4 mini-tickets executed (#007-KG003, #008-CTA-AUDIT, #009-AUTO-PROPAGATE, #010) empirically validating each upstream release.
- 3 adopter ADRs (Counterbook ADR-0025 + ADR-0026 + ADR-0027) codifying local governance policy and serving as the canonical example of Cluster F.
- Empirical architectural discoveries beyond spec: >10x bulk-create perf gain (D-USU.0), HARD REJECT security posture (D-AUTO.0), saturation indicator (#010).
- Reference adopter status formalized post-#010 (Phase 6 Day 5).
TenantShield's Phase 6 architectural maturity is, empirically, the result of Counterbook's adoption pressure. Cluster G is the structured acknowledgment of that asymmetric value flow.
Lessons learned (cross-project)
- Owner-as-coordinator scales for small-N cohorts. The tri-session protocol works fluently with one adopter. Track B / C onboarding is the empirical test of where the model strains.
- Empirical-first discipline pays dividends compound. The 71-tarea empirical-first streak sustained through Phase 6 reflects a protocol that, once internalised, costs less than alternatives. Rule 70 archaeology saved D-VAL.0 + D-NEST.0 + (partially) D-PERF.0 -- each a tarea that would have been built before being verified unnecessary.
- DR-004 enforcement protocol (no AI attribution in commit messages) operated mandatory per-GO across the full phase. The invariant held: every commit + tag + memory file emerged clean. The discipline cost is small once the self-check pattern is reflexive.
- Memory refresh cadence per phase boundary (D-MEM.0..5 + prior D-MEM.* in earlier phases) preserves cross-conversation continuity. The B' / B'' / B''' / B'''' incremental naming convention extended naturally without requiring section re-numbering.
Phase 7+ trajectory anticipated
The Phase 6 closure unblocks several Phase 7 trajectories. None of them is yet ratified; this section documents anticipated work for Owner discretion.
- Multi-adopter cohort scaling. Track B / C onboarding will test the Cluster E coordination protocol limits. Specific scaling primitives (issue templates, response SLA conventions, automated pin-bump verification) may emerge as Phase 7 deliverables.
- PyPI public publish. The Phase 6 D-DIST.0 TestPyPI workflow is
the staging surface; the migration to public PyPI (
pip install tenantshieldfrom the default index) is a Phase 7 decision awaiting broader cohort feedback signal. - Production performance optimization based on adopter data. The Cluster H Day 5 finding -- that the Django signal chain is inherently efficient -- generalises to other code paths only if adopter telemetry confirms. Phase 7 may receive observability data from cohort production deployments and surface optimization opportunities.
- Cross-adapter parity audit. The SQLAlchemy adapter (Phases 3-5) and Django adapter (Phases 2, 6) have evolved at different cadences. A Phase 7 parity audit may surface API surface divergences worth normalising.
Closure
Phase 6 closes with all 13 ADR-0015 findings cleared, 5 incremental
releases shipped, the reference adopter (Counterbook) producing 4
empirically-validated integration cycles, and 7 Pattern Clusters +
5 Rules added to the project's architectural vocabulary. Tag
v0.6.0-alpha marks the milestone. __version__ advances from
0.5.4a0 to 0.6.0a0 per Rule 49 P1 (5th canonical Phase root
application).