update_skill(): writes new Skill content to skills/<skill_id>/SKILL.md and
commits it (03-C §3.8: file write + git commit must be atomic -- the DB
insert only happens after the commit succeeds, so a git failure naturally
leaves no orphaned skill_iteration row, no separate rollback machinery
needed), rejects a missing triggered_by_bug_id (MISSING_TRIGGER_REF).
rollback_skill(): restores the pre-iteration content from
before_git_commit_sha and commits *that* as a new commit + new
skill_iteration row (03-C §3.9: rollback is itself a new iteration, not a
history rewrite); the rollback record's triggered_by_bug_id reuses the
original iteration's, since c_skill_rollback's input contract has no bug_id
of its own and that FK is NOT NULL.
repo_path has no default (caught and fixed during this Unit, not shipped
with the bug): an earlier draft defaulted it to this repo's own root,
which would have made any test that forgot to override it silently commit
into graphlemon's actual git history. Every call site must now be
explicit; git log confirms nothing leaked into this repo while building
and testing it.
Resolves U-015's deferred skill_defect gap: re-reading 04-P §4.3's own
transition table, bug_recorded (c_bug_record_create alone) and
skill_iteration_triggered (-> c_skill_update) are separate, sequential
transitions, not one atomic call -- so 03-C §3.10's "必须同时创建
skill_iteration_suggestion" is a same-flow requirement, not a same-API-call
one. bug_record.py already accepted skill_defect (it was never actually
rejected, just undocumented as resolved); update_skill() now fills in
bug_record.skill_iteration_suggestion_id once the real iteration exists.
Known gap, not this Unit's job: no real Skill content has been migrated
from the Hermes profiles yet (05 §5.1 names the skills; agent_profile.py's
frontmatter only references them by name) -- tests seed a placeholder
skill file, same pattern as U-010/011 seeding placeholder artifacts for
upstream producers that don't exist yet.
10 new stdlib unittest cases, all real (git + sqlite, no LLM call needed --
same category as U-013's worktree tests). 167 total across U-001-018, all
passing.
This closes PH2-S2. REQ-08 is now real code, and U-015's skill_defect note
is resolved rather than left permanently deferred.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>