feat(P06): 3-tier versioning, branch hierarchy enforcement, ARCHITECTURE-PLAN synthesis

---ci---
phase: 6
milestone: v0.5
status: complete
decisions:
  - id: D-006
    decision: Research as intermediate work product
    rationale: Conclusions update .ci/ files; full research doc intentionally not preserved
    confidence: 0.90
  - id: D-007
    decision: Branch hierarchy enforcement: main > milestone > phase
    rationale: Prevents out-of-order merges and semantically wrong tags
    confidence: 0.92
  - id: D-008
    decision: 3-tier versioning: NFR/feature/schema-breaking
    rationale: Patch per phase (NFR/feature) or minor per phase (schema-breaking); milestone gets minor (feature) or major (schema-breaking)
    confidence: 0.95
requirements:
  covered: [VER-06, BRANCH-01, BRANCH-02, ARCH-01]
---/ci---

- Synthesize ARCHITECTURE-PLAN.md into .ci/ci/ARCHITECTURE.md (expanded 51→230 lines)
- Add D-006/D-007/D-008 to .ci/ci/PROJECT.md key decisions table
- Delete ARCHITECTURE-PLAN.md after synthesis
- Rewrite ship.md with 3-tier versioning model + branch hierarchy merge flows
- Rewrite branch-strategy.md with 3-tier versioning + branch hierarchy + version validation
- Add MilestoneType to config types
- Replace isNfrMilestone() with getMilestoneType() returning nfr|feature|schema-breaking
- Add validateMergeOrder(), mergeMilestoneBranch(), computeMilestoneTag() to GitBranch
- Add computeShipVersion(), validateVersionOrder(), resolveMergeTarget() to ship command
- Remove hardcoded v0.5. from error-recovery rollback
- Create .githooks/pre-push for semver ordering + branch hierarchy validation
- Add 15 new tests (370 total, all passing)
This commit is contained in:
Jon Chery
2026-05-29 17:18:10 +00:00
parent 3d069319b5
commit ab6af144b7
14 changed files with 696 additions and 93 deletions
+14 -5
View File
@@ -7,6 +7,8 @@ import {
import { parseCommitMessage } from "./commit-parser.js";
import { PipelineStage } from "../types/pipeline.js";
import { MilestoneType } from "../types/config.js";
export interface ProjectState {
currentPhase: number;
currentMilestone: string;
@@ -342,13 +344,20 @@ export class GitContext {
return null;
}
isNfrMilestone(): boolean {
getMilestoneType(): MilestoneType {
const commits = this.getRecentCommits(100);
let hasAnyCiCommit = false;
for (const commit of commits) {
if (commit.type === "feat" && commit.ci) {
return false;
}
if (!commit.ci) continue;
hasAnyCiCommit = true;
if (commit.type === "feat") return "feature";
if (commit.type === "refactor" || commit.scope === "init") return "schema-breaking";
}
return true;
if (!hasAnyCiCommit) return "nfr";
return "nfr";
}
isNfrMilestone(): boolean {
return this.getMilestoneType() === "nfr";
}
}