Implementation Plan: Primary & Merge Vocabulary Disambiguation (Track 1)
Branch: feat/terminology-primary-merge-disambiguation | Date: 2026-07-16 | Spec: spec.md Input: Feature specification from kitty-specs/primary-merge-vocabulary-01KXP11C/spec.md
Summary
Give the overloaded terms "primary" (4 senses: PRIMARY partition / Primary Branch / repository root checkout / target ref) and "merge" (3 operations: lane consolidation / branch integration / publish to origin) one canonical term each across the glossary (docs/context/), prose/--help/docstrings, and a small set of SAFE code changes — with every shipped identifier, serialized key, and CLI/command name left byte-identical. This is Track 1 of the #2653 epic; the high-risk Sense-C repository_root_checkout_* code rename is Track 2 (#2730) and the src/glossary/ package removal is #2727.
Technical approach: a classified bulk edit. A plan-phase occurrence_map.yaml (this file's sibling) partitions every in-scope occurrence into CLARIFY-PROSE / RENAME (internal only) / EXEMPT / DEFER-Track-2 / DO-NOT-TOUCH-unrelated. The load-bearing acceptance property is invariance: exempt tokens byte-identical and the full suite + ruff + mypy --strict green. Enforcement is honestly scoped — Track 1 ships no automated primary/merge sense-guard (the terminology guard is a hardcoded 2-literal grep); sense-correctness is review-enforced against the occurrence map, and a durable alias-ban guard is deferred to Track 2 (FR-011).
Technical Context
Language/Version: Python 3.11+ (docs/prose + light code; no runtime behavior change) Primary Dependencies: docs/context/ glossary prose; src/specify_cli/ (resolver + merge/partition helpers); glossary/ legacy prose. No new deps. Storage: N/A — Markdown/YAML text + Python symbol renames; no data migration. Testing: existing test_git_ops, test_tasks_compat_surface, test_precondition_ref_unification, test_partition_authority_characterization, merge-helper importers (~13); gate suites: docs anti-sprawl ratchet (--strict), description-length, relative-link, test_no_legacy_terminology.py; arch pins (test_mission_runtime_surface, test_shared_package_boundary) must stay green (exempt-surface guard). ATDD red-first for the resolver consolidation + any new alias-ban assertions. Target Platform: Linux/CI (repo tooling) Project Type: single (docs + light code) Performance Goals: N/A (no hot path renamed — Sense-C deferred) Constraints: INVARIANCE — exempt tokens byte-identical (spec C-001/C-002/C-004); ruff + mypy --strict clean with zero new suppressions; sequence around in-flight mission-step-authority-01KXNZMT (C-006). Scale/Scope: Bounded. Mostly prose (glossary entries + --help/docstring/ADR/CLAUDE.md sweep) + 3-4 internal symbol renames + one resolver consolidation. The occurrence map sizes the exact edit set; expectation is a concentrated, low-LOC change.
Charter Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
- Single canonical authority — PASS.
occurrence_map.yamlis the single authority for what changes; the spec + research are the single authority for the canonical terms. No improvised rename lists. - Terminology adherence — PASS (and is the point). Establishes canonical terms per sense;
docs/context/is the canonical prose-glossary home. Enforcement scoped honestly (FR-011) — no false claim of gate coverage. - ATDD-first — PASS. Red-first for the
resolve_primary_branchconsolidation (compat-guard + behavior) and any opt-in alias-ban assertions precede edits. - Architectural gate discipline — PASS. No gate relaxed; exempt-surface pins (
test_mission_runtime_surface,test_shared_package_boundary,test_tasks_compat_surface) stay green; changes to them are contract updates, not weakenings. - Campsite / bulk-edit discipline (DIRECTIVE_035) — PASS.
change_mode: bulk_edit; occurrence map actions all 8 categories; ambiguous → human decision. - No version prescription — PASS. No patch number assigned (PO superimposes at release).
No violations → Complexity Tracking left empty.
Project Structure
Documentation (this mission)
kitty-specs/primary-merge-vocabulary-01KXP11C/
├── plan.md # This file
├── spec.md # Mission spec (squad-hardened)
├── occurrence_map.yaml # REQUIRED bulk-edit classification (sibling of this file)
├── research.md # Phase 0 (grounded in scratchpad research report)
├── quickstart.md # Phase 1 verification walkthrough
├── contracts/ # Phase 1 (exempt-surface + canonical-term contracts)
└── tasks.md # Phase 2 (/spec-kitty.tasks — NOT created here)
Source Code (repository root) — surfaces this mission touches
docs/context/
├── orchestration.md # FR-001/002 — add primary A/B/D + merge 1/2/3 sense entries (append-only; C-006)
└── execution.md # FR-001 — Sense-C "repository root checkout" prose entry (prose only; C-002)
glossary/
├── README.md # FR-005 — repoint stale glossary/contexts/ links → docs/context/
├── historical-terms.md # FR-006 — fold into docs/context/ (moves[])
└── naming-decision-tool-vs-agent.md # FR-006 — fold into docs/context/ (moves[])
src/specify_cli/
├── core/git_ops.py # FR-007 — canonical resolve_primary_branch (keep)
├── cli/commands/agent/tasks_shared.py # FR-007 — delegating shim (compat re-export decision)
├── cli/commands/agent/mission_branch_context.py # FR-007 — _resolve_primary_branch_for_recommendation (fold/scope-out)
├── lanes/merge.py # FR-008 — merge_lane_to_mission / merge_mission_to_target (internal rename)
├── cli/commands/implement_cores.py # FR-008 — _primary_ref_for (internal rename)
├── coordination/commit_router.py # FR-008 (optional) — _resolve_primary_target_branch
├── cli/commands/merge.py # FR-003 — --help / docstring clarify
└── cli/commands/agent/mission_accept_merge.py # FR-003 — accept→merge --help clarify
CLAUDE.md # FR-003/011 — condense 3 warnings → 1 glossary pointer that still names the footgun
docs/adr/3.x/2026-06-24-2-*.md # FR-003 — clarify the conflating "primary" paragraph
Structure Decision: Single project. Edits are concentrated in docs/context/ (glossary), a handful of src/specify_cli/ modules (safe renames + resolver consolidation), and top-level prose (glossary/, CLAUDE.md, one ADR). No new directories except relocated prose under docs/context/.
Complexity Tracking
No Charter Check violations → intentionally empty.
Implementation Concern Map
> Concerns are NOT work packages. /spec-kitty.tasks translates these into WPs.
IC-01 — Glossary sense entries (docs/context/)
- Purpose: Author one canonical glossary entry per sense (4 primary + 3 merge) in
orchestration.md/execution.mdusing the existing per-term table format, withDo NOT use when+ cross-links. - Relevant requirements: FR-001, FR-002, FR-004 (Primary Branch already exists — extend, don't duplicate).
- Affected surfaces:
docs/context/orchestration.md(append-only blocks — C-006),docs/context/execution.md. - Sequencing/depends-on: none (but coordinate with C-06 sequencing vs
mission-step-authority). - Risks: hot-file collision on
orchestration.mdwith in-flightmission-step-authority-01KXNZMT(C-006) → keep additions append-only; description-length gate (≤180) on any new page.
IC-02 — Prose / --help / docstring disambiguation sweep
- Purpose: Reword the conflating surfaces to name the specific sense; condense CLAUDE.md's 3 warnings into one glossary pointer that still names the partition-vs-branch footgun.
- Relevant requirements: FR-003, FR-011.
- Affected surfaces:
cli/commands/merge.py,cli/commands/agent/mission_accept_merge.py,lanes/merge.py, merge-step doctrine prompts, ADR2026-06-24-2,CLAUDE.md. - Sequencing/depends-on: IC-01 (entries must exist to cross-reference).
- Risks: a
--help/prose string asserted byte-exact in a test → update assertion in lockstep or treat as exempt (edge case).
IC-03 — Glossary-infrastructure cleanup
- Purpose: One prose-glossary home — repoint
glossary/README.mdand fold legacyglossary/prose intodocs/context/. - Relevant requirements: FR-005, FR-006.
- Affected surfaces:
glossary/README.md,glossary/historical-terms.md,glossary/naming-decision-tool-vs-agent.md, inbound references (note downstream #1341/#648). - Sequencing/depends-on: none.
- Risks: moving docs breaks
../relative links (relative_link_fixer --check) and.githubsymlinks (git add -f).
IC-04 — resolve_primary_branch consolidation
- Purpose: One canonical resolver behavior; resolve the delegating-shim compat re-export and the recommendation re-implementation (fold-with-bias or scope-out) — DIRECTIVE_044 unification.
- Relevant requirements: FR-007.
- Affected surfaces:
core/git_ops.py,cli/commands/agent/tasks_shared.py,cli/commands/agent/tasks.py(__all__),cli/commands/agent/mission_branch_context.py; guardtest_tasks_compat_surface. - Sequencing/depends-on: none.
- Risks:
tasks.py.__all__+test_tasks_compat_surfaceare a pinned compat contract — must move in lockstep; the recommendation re-impl has a deliberate no-feature-bias behavior that must be preserved.
IC-05 — Internal helper renames (merge + Sense-D)
- Purpose: Align genuinely internal helper names to canonical operations;
is_primary_artifact_kindEXCLUDED (public). - Relevant requirements: FR-008.
- Affected surfaces:
lanes/merge.py(+orchestrator_api/commands.pycallers, ~13 test importers,write_candidate_classification.yamlarch fixture),implement_cores.py(+implement.py, 2 pinning tests), optionalcommit_router.py. - Sequencing/depends-on: IC-04 (same review area, sequence to avoid churn).
- Risks: helpers are broadly imported (not "internal-only") — every caller + arch fixture must move together or the surface-audit gate reds.
IC-06 — Occurrence-map authoring + enforcement disclosure
- Purpose: The
occurrence_map.yaml(all 8 categories) is the single change authority; state the enforcement model honestly (FR-011). - Relevant requirements: FR-009, FR-011, NFR-004, C-005.
- Affected surfaces:
occurrence_map.yaml; spec FR-011 disclosure; optional opt-in alias-ban assertion for non-Sense-C aliases. - Sequencing/depends-on: authored at plan time (this phase); enforced at implement.
- Risks: single-term schema vs two-term mission — modeled with
primaryheadline + both-term category policy + exceptions (see occurrence_map notes).