Research: Upgrade and Windows drift
Grounding evidence and seam census: research-memo.md. This file records the decisions the plan rests on.
D1 — Fix false drift at the command-skill owner
- Decision:
command_installertreats on-disk bytes equal to the current canonical rendering as fresh, and the adoption pass refreshes the recordedcontent_hashto that digest.probeandverifystay hash-versus-manifest and become correct once the manifest is refreshed. - Rationale: the owner already renders canonical bytes in
prepare_commands; the upgrade already runs that adoption pass (_repair_stale_command_manifest) before probing. Probing a second canonical render in the provider would duplicate rendering and leave the manifest stale for every other reader. - Alternatives considered: canonical check inside
CommandSkillsProvider.probe(duplicate render, manifest still stale); reclassify asstale(contract "stale" means disk equals manifest but not canonical, the opposite case).
D2 — Consent is the existing explicit repair
- Decision:
CommandSkillsProvider.repairpassesApplyConsent(automatic=True, overwrite_paths=<drifted rels>), likeAgentProfilesProvider.repair;preserve()lets aconsent_requiredpath through when it is named inoverwrite_paths. No new flag. - Rationale: matches agent-profile prior art and drift-policy Rules 3 and 5;
_apply_auto_repairsnever hands drifted statuses to a provider, so unattended upgrade stays report-only. - Alternatives considered: expose
--repair-drift=overwriteon upgrade (new public flag, escalation per C-002); auto-overwrite on upgrade (violates C-003).
D3 — Compare Git object ids for planning artifacts
- Decision:
_files_changed_vs_refcomparesgit hash-object --stdin-paths(each path's clean filter applied) with the object id at<ref>:<rel>from onegit ls-tree. Any git error keeps the file as changed. - Rationale: identical to what
git addwould store, so a line-ending-only difference compares equal and a real token change (in any line ending) compares unequal (C-004). - Alternatives considered: normalize CRLF to LF in Python (diverges from
.gitattributessemantics, e.g.-textfiles);git diff --quiet <ref> -- <path>per file (one subprocess per file); changeshow_blob(other callers rely on raw bytes).
D4 — Mission workspace is a standalone clone
- Decision: the mission runs in a standalone local clone at
../sk-upgrade-windows-drift, not a linked worktree. - Rationale: at
fb7c92d6f0planning commands for alanes_with_coordmission resolve from the repository root checkout; a linked worktree is accepted as an owned checkout only forsingle_branch. A clone is its own repository root, keeps the requested topology, and leaves the primary checkout untouched. Logged as tooling friction. - Alternatives considered:
single_branchwith--owned-checkout(loses the requested topology); working in the primary checkout (forbidden by the brief).