# Implementation Plan: Spec 439 - Branch Topology and Local Evidence Truth **Branch**: feat/439-branch-topology-local-evidence-truth | **Date**: 2026-07-10 | **Corrected**: 2026-07-11 | **Spec**: specs/439-branch-topology-local-evidence-truth/spec.md **Input**: Corrected Spec 439 branch-topology and engineering-evidence remediation. **Status**: Implemented and reconciled; merge-ready locally with an external activation condition. **Lifecycle boundary**: Imperative phase text and readiness gates below preserve the approved preparation-time execution plan. Current task completion, evidence, residuals, and merge status are owned by `tasks.md` and `implementation-report.md`. ## Summary Implement one bounded repository-governance slice that: 1. first replaces the obsolete universal dev branch rule through the current Constitution Amendment Procedure; 2. validates that amendment before synchronizing directly conflicting authoritative instructions; 3. resolves branch family separately from the concrete Git ref; 4. maps ordinary platform work to platform-dev and ordinary website work to website-dev; 5. permits dev only for explicitly classified repository integration/promotion; 6. removes silent stream fallback to dev, origin/dev, or HEAD~1; 7. preserves the original test process result through report refresh; 8. makes existing blocking/advisory budget profiles affect the final command result correctly; 9. validates required JUnit/report evidence and detects contradictions; 10. proves the contract with deterministic local fixtures. The implementation changes governance documents, repository tooling, tests, and existing local evidence/report wiring only. It does not change product runtime, rendered surfaces, data, RBAC, OperationRun behavior, deployment, or remote branch administration. ## Technical Context **Language/Version**: Markdown governance documents; Bash; PHP 8.4.15 for existing test-support code **Framework/Test Stack**: Laravel 12 repository, Pest 4, PHPUnit 12, Symfony Process already available **Storage**: Existing filesystem test artifacts only; no database changes **Project Type**: Monorepo with apps/platform, apps/website, root scripts, Spec Kit, and Gitea workflow declarations **Primary Constraints**: Constitution amendment first; Sail-first for PHP/Pest; no network-dependent fixtures; no product runtime; no new dependency; no generic branch graph **Performance Goal**: Focused fixtures remain small and deterministic; existing Fast Feedback and Confidence budgets remain the no-regression boundary **Scale/Scope**: Three known long-lived branches, fixed work classifications, existing local lane/report entry points ## Correction Preflight Evidence Spec correction began on feat/439-branch-topology-local-evidence-truth at 71e3745a with only the existing untracked Spec 439 package. Confirmed current repo truth: - Constitution 2.16.0 still contains the universal dev branch rule. - The Amendment Procedure requires an explicit Constitution update PR, rationale, impacted templates/specs, SemVer decision, and Last Amended update. - No authoritative repo rule requires a separate preceding Amendment Spec. - Agents.md still contains directly conflicting universal dev instructions. - The current changed-file guard defaults to origin/dev and then HEAD~1. - The PR fast-feedback workflow explicitly fetches/passes origin/dev. - TestLaneManifest::renderLatestReport() supplies exitCode 0 and returns 0 unconditionally. - TestLaneReport::parseJUnit() currently extracts duration data only. - TestLaneBudget already owns trigger-aware blocking/advisory classifications. - Spec 438 remains deferred and unimplemented. Implementation Phase 0 MUST revalidate these call paths and governance rules on current HEAD. Material drift requires reconciliation of the active artifacts before mutation. ## Governance Decision ### Amendment posture The branch-topology amendment is inside Spec 439 scope and is Phase 1. It is not an external prerequisite. The same Spec 439 feature PR may contain: 1. the narrow Constitution amendment; 2. its required Sync Impact, rationale, impacted-artifact list, SemVer decision, and Last Amended update; 3. directly dependent implementation after the Phase 1 validation gate. No Phase 2-8 work is authorized before the Phase 1 amendment is applied and validated. The Amendment Procedure does not require a second feature spec, but the Constitution itself remains authoritative until Phase 1 changes it. ### SemVer handling The implementation MUST not predetermine PATCH. Replacing the universal dev rule is a semantic governance change. Phase 1 must select and justify the version under the current policy; a backward-incompatible interpretation requires MAJOR, while any MINOR decision requires an explicit rationale explaining why the change is an expansion rather than an incompatible redefinition. ### Amendment boundary Allowed: - replace only the universal dev branch rule; - define dev, platform-dev, and website-dev roles; - define scope-specific feature base, normal target, and diff baseline; - require explicit cross-stream/promotion classification; - forbid silent wrong-family and HEAD~1 fallback; - update required amendment metadata; - identify directly conflicting authoritative artifacts for Phase 2. Forbidden: - general Constitution cleanup or reduction; - UI/UX, security, architecture, provider, RBAC, OperationRun, or product-governance changes; - skill reorganization; - unrelated guidelines/docs cleanup; - runtime, deployment, or remote-administration changes. ### Amendment-first close-out evidence The Phase 1 hard execution gate remains unchanged. Close-out proof does not attempt to reconstruct wall-clock mutation order from the final diff. It uses the final Constitution amendment, exact boundary and unrelated-scope controls, synchronized dependent instructions and implementation, task/report process attestation, and the absence of a conflicting final state. No commit, tag, patch, or snapshot checkpoint was mandated before Spec 439 implementation began; none is retroactively claimed. Any future plan requiring independently reconstructable chronology must define and capture that checkpoint before its first mutation. ## Development Stream and Merge Strategy - **Work classification**: repository-governance. - **Feature base**: platform-dev. - **Feature branch**: feat/439-branch-topology-local-evidence-truth. - **Normal merge target**: platform-dev. - **Promotion to dev**: later explicit integration work, outside Spec 439. - **Website convergence**: no delivery contract is created; website family behavior is proven through deterministic fixtures only. - **Constitution amendment delivery**: included in the same feature PR and applied before dependent implementation on the feature branch. This strategy does not rename, synchronize, merge, or rebase long-lived branches. ## Canonical Branch Topology | Branch | Role | Ordinary Feature Base | Normal Target | Diff Baseline | |---|---|---|---|---| | dev | Repository-wide integration and promotion | explicit only | explicit promotion/integration | explicit | | platform-dev | TenantPilot platform integration | platform-dev | platform-dev | platform-dev | | website-dev | Website integration | website-dev | website-dev | website-dev | Repository-governance work is explicitly classified by affected scope. Spec 439 is platform-owned repository governance and therefore uses platform-dev for base, target, and baseline. Cross-stream and promotion work must declare a target and may target dev. The existence of dev never implies fallback. ## Unified Resolver Contract The resolver makes two separate decisions. This section intentionally matches spec.md verbatim in substance and priority. ### Stage 1 - Resolve the branch family Priority: 1. explicit CLI or workflow branch-family input; 2. pull-request target branch from event context; 3. active spec metadata or explicit spec classification; 4. current feature-branch naming plus repository-scope signals; 5. otherwise fail closed. Rules: - Explicit input MUST be validated against a known branch family. - A present PR target is authoritative when it maps to a known branch role. - Spec metadata MUST NOT contradict a valid PR target. - Branch-name and path/scope signals are subordinate detection aids and are never sufficient when ambiguous. - The highest-priority usable signal selects the candidate family, but every other present authoritative signal MUST be checked for conflict. - A real conflict, including explicit family platform with PR target website-dev, MUST fail with an actionable conflict diagnostic. - No source may silently override a contradictory authoritative source. - There is no silent default to dev. ### Stage 2 - Resolve the concrete Git reference After the branch family is known: 1. explicit validated Git ref for the selected branch family; 2. matching remote ref, for example origin/platform-dev; 3. matching local ref, for example platform-dev; 4. validate ancestry and compute the merge base; 5. otherwise fail closed. Rules: - Only refs belonging to the selected branch family are valid. - Missing origin/platform-dev MUST NOT fall back to origin/dev. - Missing origin/website-dev MUST NOT fall back to origin/dev. - HEAD~1 is not a valid integration-baseline fallback. - An explicit cross-stream/promotion target may use dev only after Stage 1 classified the work accordingly. - Output MUST include branch family, expected integration branch, selected ref, target commit, merge-base commit, and resulting base range. - Failure output MUST include the conflicting or attempted signals/refs, explicit override guidance, and confirmation that no diff ran. ### Terminology - **Branch family**: The workstream/integration role selected in Stage 1. - **Concrete Git ref**: The validated remote, local, or explicit ref selected in Stage 2. - **Merge base**: The common commit used to derive feature-relative changes. - **Feature base**: The branch from which ordinary work in a family starts. - **Normal PR target**: The default integration target for ordinary work in a family. - **Promotion target**: An explicitly declared cross-stream/repository integration target, which may be dev. ## Proposed Repository Changes ### 1. Narrow Constitution branch-topology amendment Update .specify/memory/constitution.md only as authorized by FR-001 through FR-007: - replace the universal dev statement; - define all three branch roles and scope-specific routing; - require explicit cross-stream/promotion classification; - forbid silent wrong-family and HEAD~1 fallback; - update the Sync Impact Report, SemVer version, and Last Amended; - include rationale and impacted templates/specs/instructions. Validate the amendment diff before any other file changes. ### 2. Direct authoritative instruction synchronization After Phase 1 validation: - update only directly conflicting branch instructions in Agents.md; - inspect branch-related authoritative skills/instructions and change only confirmed contradictions; - retain valid platform-dev and promotion guidance; - record unrelated drift as residual debt; - do not rewrite historical completed/deferred specs. ### 3. Small two-stage branch resolver Add one small root executable, expected at scripts/resolve-feature-base unless Phase 0 proves an existing narrower shared path. The resolver owns only: - fixed branch families and current roles; - Stage 1 signal validation/conflict detection; - Stage 2 family-matching ref resolution; - ancestry and merge-base calculation; - fail-closed diagnostics; - stable human-readable output plus the smallest machine-readable output needed by existing consumers. It does not fetch, mutate branches, inspect arbitrary repositories, manage releases, or model user-configurable graphs. ### 4. Existing changed-file guard integration Update scripts/check-ui-productization-coverage to consume the unified resolver while preserving: - its explicit base argument; - committed/staged/unstaged/untracked collection; - existing productization checks; - exit 2 before diff when family/ref resolution fails. The guard must print family, ref, target, merge base, and base range. No website productization framework is introduced. ### 5. Existing repository-side workflow declaration coherence Inspect .gitea/workflows/test-pr-fast-feedback.yml and contract tests. If current event syntax is repo-locally provable, pass the actual PR target through the unified family/ref contract instead of hard-coded origin/dev. Preserve all triggers, jobs, lanes, artifacts, and schedules. If syntax is not repo-locally provable, leave the workflow unchanged, record the residual, and do not claim remote validation. TestLaneManifest::MAINLINE_BRANCH = dev and main-confidence dev push remain valid promotion semantics. ### 6. Test execution and report-result preservation Extend the existing TestLaneManifest/TestLaneReport path: - persist the real test process result during finalizeLane(); - carry it through renderLatestReport(); - derive one final result from execution, required evidence, evidence consistency, report generation, and blocking budget truth; - keep advisory warnings non-blocking; - preserve both test and report-generation failure contexts; - extend the existing schema minimally. ### 7. JUnit validity and contradiction detection Extend the smallest existing helper to expose: - existence and parse validity; - test, failure, error, and skipped counts; - derived evidence status; - affected evidence path in diagnostics. Missing/malformed evidence, JUnit failure with passed claim, and failed process with apparently successful evidence cannot normalize to PASS. ### 8. Blocking versus advisory budgets Keep TestLaneBudget::enforcementProfiles() authoritative: - hard-fail plus over-budget returns non-zero; - hard-fail within-tolerance warning is non-blocking absent another failure; - soft-warn remains visible and non-blocking; - trend-only remains informational; - missing data required by an active blocking profile fails closed. No threshold or profile classification changes are authorized merely to regain green output. ## Constitution Check ### Readiness gate - **Amendment Procedure**: PASS for implementation readiness. Spec 439 authorizes an explicit Phase 1 update with required rationale, impact list, SemVer, and Last Amended handling. - **Current universal dev rule**: Known contradiction to be replaced by the first mutation; it does not authorize dependent work before Phase 1 validation. - **PROP-001 / ABSTR-001 / BLOAT-001**: PASS. One fixed resolver and one narrow rule replacement are justified by current platform/website and evidence consumers; no general framework. - **SPEC-DISC-001 / LAYER-001**: PASS. Governance, branch truth, and evidence truth remain one coherent repair rather than multiple micro-specs or parallel report layers. - **TEST-TRUTH-001 / TEST-GOV-001**: PASS by design. Unit and bounded Feature tests protect actual outcomes; Fast Feedback and Confidence are affected lanes; no heavy family. - **PERSIST-001 / STATE-001**: N/A for product persistence/state. - **PSC-001 / UI-COV-001**: N/A - no rendered UI. - **RBAC / workspace / provider / OperationRun / customer output**: N/A. ### Phase gate The plan is ready to start Phase 0 and Phase 1. It is not permission to start Phase 2-8 early. Any dependent diff before recorded Phase 1 validation is a plan violation and must be removed or the implementation stopped. ## Product and Runtime Impact - **Platform runtime**: none. - **Website runtime**: none. - **Database/migrations**: none. - **Routes/UI/Filament/Livewire**: none. - **RBAC/policies/capabilities**: none. - **OperationRun/audit/product evidence**: none. - **Customer output**: none. - **Assets**: none; filament:assets is not required. - **Deployment**: no env, migration, queue, scheduler, storage, proxy, or Dokploy change. ## Project Structure Expected implementation surfaces, subject to Phase 0 confirmation: .specify/memory/constitution.md Agents.md scripts/ ├── resolve-feature-base ├── check-ui-productization-coverage ├── platform-test-lane # only if propagation requires it └── platform-test-report # only if propagation requires it .gitea/workflows/ └── test-pr-fast-feedback.yml # conditional existing-target correction apps/platform/ ├── composer.json # only if compatible entry arguments require it └── tests/ ├── Support/ │ ├── TestLaneManifest.php │ ├── TestLaneReport.php │ └── TestLaneBudget.php # authoritative profiles; expected unchanged ├── Unit/Support/ │ ├── TestLaneReportTest.php │ └── TestLaneBudgetTest.php └── Feature/Guards/ ├── BranchTopologyContractTest.php ├── ConstitutionBranchTopologyContractTest.php ├── TestLaneCommandContractTest.php ├── TestLaneArtifactsContractTest.php ├── CiLaneFailureClassificationContractTest.php └── directly affected Ci workflow contract tests specs/439-branch-topology-local-evidence-truth/ ├── spec.md ├── plan.md ├── tasks.md ├── checklists/requirements.md ├── evidence/baseline-attribution.json # compact paired close-out evidence └── implementation-report.md # created only during Phase 8 Forbidden runtime paths include apps/platform/app, apps/platform/database, apps/platform/routes, apps/platform/resources, and apps/website/src unless the active spec is corrected before any such change. ## Test Strategy ### A. Constitution and instruction contracts Required cases: 1. branch roles and scope routing are present; 2. universal dev feature-base wording is absent from authoritative current instructions; 3. cross-stream/promotion requires explicit target; 4. wrong-family and HEAD~1 fallback are forbidden; 5. unrelated Constitution principles remain unchanged; 6. Sync Impact, rationale, SemVer, and Last Amended are coherent. ### B. Branch-topology fixtures Use Pest with Symfony Process and isolated temporary Git repositories. Each fixture configures identity, commits, branches, and refs without network. Required cases: 1. platform remote-ref priority; 2. platform local-ref fallback; 3. website remote-ref priority; 4. website local-ref fallback; 5. explicit promotion to dev; 6. missing platform refs fail closed; 7. missing website refs fail closed; 8. diverged platform topology returns only the feature path; 9. diverged website topology returns only the feature path; 10. explicit platform family plus PR target website-dev fails; 11. ambiguous name/path/spec signals fail; 12. explicit wrong-family ref is rejected; 13. success/failure diagnostics contain required fields. ### C. Evidence-truth fixtures Required cases: 1. failed process remains failed after refresh; 2. passed process remains passed; 3. blocking fast-feedback pull-request budget breach returns non-zero; 4. advisory confidence breach remains warning and zero absent another failure; 5. JUnit failures/errors plus passed claim is contradiction/non-zero; 6. missing required JUnit is non-zero; 7. malformed required JUnit is non-zero; 8. test failure plus report-generation failure preserves both contexts; 9. missing required report artifacts remain publication failure; 10. existing successful consumers remain readable. ### D. Focused regression set At minimum: - new Constitution/branch-topology contract tests; - tests/Unit/Support/TestLaneReportTest.php; - tests/Unit/Support/TestLaneBudgetTest.php; - tests/Feature/Guards/CiLaneFailureClassificationContractTest.php; - tests/Feature/Guards/TestLaneCommandContractTest.php; - tests/Feature/Guards/TestLaneArtifactsContractTest.php; - tests/Feature/Guards/TestLaneManifestTest.php; - directly affected workflow contract tests; - fast-feedback and confidence lanes; - Sail Pint on dirty PHP files; - git diff --check; - forbidden-path and Spec 438 unchanged checks. ### E. Full-suite decision A full product suite is not automatic because no product runtime changes. Fast Feedback and Confidence are required because the shared runner/report path and enforcement profiles change. Browser, PostgreSQL, and Heavy Governance are N/A. Discovering broader cost requires prior spec/plan correction rather than late implicit expansion. **Test-governance preparation outcome**: document-in-feature. The bounded Unit/Feature fixture and lane cost is owned and reported by Spec 439; structural remote-CI or release-governance work remains a follow-up-spec. ## Mandatory Implementation Phases ### Phase 0 - Revalidate Spec readiness - Recheck branch, HEAD, dirty state, local refs, active package, and no-fetch posture. - Reconfirm Amendment Procedure and absence of a mandatory separate Amendment Spec. - Reproduce or statically trace every named defect and direct consumer. - Protect Specs 437/438 and record baselines. - Stop or reconcile stale assumptions before mutation. ### Phase 1 - Apply the narrowly scoped Constitution branch-topology amendment - Identify the exact obsolete universal dev rule. - Amend only branch roles/routing/fallback rules plus required metadata. - Choose and justify SemVer under current policy; never assume PATCH. - Update Sync Impact, rationale, impacted artifacts, and Last Amended. - Validate the amendment diff and record the Phase 1 gate. **Hard Gate**: No Phase 2-8 file may change before this gate passes. ### Phase 2 - Synchronize directly conflicting authoritative instructions - Align Agents.md and only preflight-confirmed authoritative contradictions. - Retain valid promotion and platform-dev guidance. - Add/update focused contract checks for synchronized branch wording. - Residualize non-authoritative or unrelated drift. ### Phase 3 - Implement branch-family and concrete-reference resolution - Add failing two-stage resolver fixtures first. - Implement fixed Stage 1 family selection/conflict validation. - Implement fixed Stage 2 family-matching ref/merge-base resolution. - Add success and fail-closed diagnostics. ### Phase 4 - Update local diff guards and affected repository-side workflow declarations - Integrate the resolver into the current changed-file guard. - Preserve explicit-base and all working-tree change sources. - Correct the existing PR target declaration only when repo-locally provable. - Keep all existing triggers, lanes, schedules, and deployment behavior unchanged. ### Phase 5 - Repair local test/report evidence truth - Add failing execution/refresh/JUnit/report fixtures first. - Persist original execution truth. - Extend required evidence metadata and contradiction detection. - Preserve dual failure contexts and compatible successful consumers. ### Phase 6 - Repair blocking/advisory budget truth - Add blocking/advisory/missing-input final-exit controls first. - Derive one final result from authoritative profiles and other failure sources. - Keep thresholds and profile ownership unchanged. - Propagate final result through existing wrappers/entry points. ### Phase 7 - Add negative fixtures and run focused proof - Complete BS-001 through BS-012 and EF-001 through EF-007. - Run Constitution/instruction, resolver, guard, report, budget, artifact, manifest, and workflow contracts. - Run Fast Feedback and Confidence. - Run formatter and diff/scope/history guards. - Record actual outputs without normalizing failures. ### Phase 8 - Produce implementation report and final reconciliation - Create implementation-report.md only now. - Reconcile every FR, INV, task, BS/EF fixture, changed file, test, lane, and residual. - Record the paired clean-baseline/feature attribution with exact SHA, environment and selection equivalence, raw exits, JUnit multiset deltas, performance/budget attribution, and artifact checksums. - Record Product Surface/browser/deployment N/A fields. - Record test-governance outcome and final PASS/PASS WITH CONDITIONS/FAIL. ## Dependencies and Execution Order - Phase 0 blocks Phase 1. - Phase 1 blocks every Phase 2-8 task. - Phase 2 blocks resolver/tooling work that depends on canonical instructions. - Phase 3 blocks Phase 4. - Phase 4 blocks Phase 5; no evidence-truth task may be prepared early. - Phase 5 blocks Phase 6; no budget-truth task may be prepared early. - Phase 7 follows the Phase 6 exit gate. - Phase 8 follows all validation. ## Parallelization Contract - No mutation is parallel with Phase 1. - Same-file Constitution, instruction, resolver, TestLaneReport, and TestLaneManifest edits are single-owner. - Branch fixtures are authored only in Phase 3; evidence fixtures start only after the Phase 4 exit gate. - Workflow declaration work waits for resolver stabilization. - Budget tests begin only after the Phase 5 exit gate and may run in parallel only with file-disjoint tasks inside Phase 6. - No task marked parallel may bypass an earlier phase gate or claim evidence before the producing task completes. ## Risk Controls | Risk | Control | |---|---| | Constitution scope expands | Exact authorized rule list, unrelated-principle diff check, Phase 1 gate | | SemVer is minimized incorrectly | Explicit policy decision and rationale; PATCH forbidden by scope | | dev is removed from valid use | Explicit promotion fixture and unchanged main-confidence semantics | | Signals silently override | Cross-check present authoritative signals and fail on conflict | | Generic branch framework | Fixed families/roles only | | Report schema consumer regression | Compatible extension and positive controls | | Blocking budget exposes debt | Preserve thresholds and report actual result | | Refresh hides failure | Persist original execution result and negative refresh fixture | | Missing evidence becomes empty success | Validity/count/path metadata and fail-closed result | | Remote-CI scope creeps | Conditional minimal existing declaration only | | Historical specs change | Baseline and final byte/diff checks | ## Complexity Tracking | New structure | Why needed | Simpler alternative rejected because | |---|---|---| | One narrow Constitution branch rule | Current universal dev rule contradicts repository stream ownership | Instruction-only workaround would violate current Constitution | | One small two-stage resolver | Family and concrete ref are different decisions with multiple existing consumers | Duplicated constants and branch-name inference preserve contradiction | | Compatible execution/evidence metadata | Refresh must preserve real test/evidence truth | Console-only state cannot survive report refresh | No product entity, status family, taxonomy, package, UI framework, or persistence layer is introduced. ## Rollout and Compatibility - Existing branches are not renamed, deleted, synchronized, rebased, or merged by implementation. - Existing explicit guard base argument remains supported when family-consistent. - Existing valid successful reports remain readable. - Existing thresholds remain unchanged. - Existing remote workflows are not activated or broadened. - Platform local review becomes available after merge to platform-dev. - Website behavior is contract proof only; delivery onto website-dev remains separate integration work. ## Implementation Readiness Assessment - Preparation Snapshot - Candidate Gate: PASS. - Spec Readiness Gate: READY. - Implementation Authorization: AUTHORIZED. - Constitution amendment is in scope and first. - The Amendment Procedure does not require a separate preceding feature spec. - Branch roles and two-stage resolver contract are explicit and synchronized with spec.md. - Evidence truth remains local and bounded. - No product or external-system decision blocks implementation. - Phase 2-8 remain conditionally blocked until Phase 1 validation, as intended. **Preparation Plan Gate**: READY - begin a separate implementation loop at Phase 0; Phase 1 is the first mandatory mutation.