diff --git a/session-logs/2026-06/2026-06-26-howard-skill-first-routing.md b/session-logs/2026-06/2026-06-26-howard-skill-first-routing.md new file mode 100644 index 00000000..9ab38643 --- /dev/null +++ b/session-logs/2026-06/2026-06-26-howard-skill-first-routing.md @@ -0,0 +1,68 @@ +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech + +## Session Summary + +Howard raised a recurring failure: when asked to "put in billing for a company" in Syncro, the session was hand-rolling raw Syncro REST API calls (`add_line_item` via `curl` from memory) instead of using the `/syncro` skill, producing malformed tickets that Winter then had to fix. He wanted a hard, durable rule that when a request maps to a known skill, the skill is used — not improvised API calls. + +Diagnosed the root cause as a routing-default failure, not a knowledge gap: the "act directly" bias plus knowing the Syncro API made hand-rolled curl the fast path, and nothing in the always-loaded CORE rules made skill use mandatory. The eight existing Syncro feedback memories describe correct API payloads but were being misread as license to free-hand the calls — notably `feedback_syncro_billing.md` §1 ("Bill with `add_line_item` directly") which meant "not the timer workflow," not "bypass the skill." Fixed by adding a **Skill-first** rule to CORE `CLAUDE.md`, creating `feedback_skill_first_routing.md` (+ index line), clarifying the ambiguous billing memory, and logging the correction to `errorlog.md`. + +Howard then expanded the requirement: he doesn't want to name skills per-request at all. He wants a session to see a request, recognize which skill covers it (doing-skill: billing, coding, etc.), AND automatically run the matching verification/quality skills (code-review, security-review, the "make it sound human" pass, rule/standards checks, lint) before declaring work done — inferred from the request and expected end result, calibrated to stakes, and cheap (using Ollama Tier-0 for classify/prose passes). This was framed as "that's why we make the skills — to double-check things are how they should be." + +Presented a three-part fix (A: CORE Definition-of-Done rule; B: on-demand `.claude/SKILL_ROUTING.md` map; C: deterministic Stop-hook backstop) and asked Howard for the enforcement tier and which work-types should auto-verify. He chose **A+B now, hold C**, with all four work-types auto-verifying (code, outbound/client-facing, Syncro/vendor, docs/wiki/memory). Implemented A+B: extended the CORE Skill-first bullet into a Definition-of-Done with a pointer to the map, authored `SKILL_ROUTING.md` (full request→doing-skill→check-skill table + stakes calibration + Ollama Tier-0 guidance), extended the memory and index line, then committed and pushed. + +## Key Decisions + +- **Fix the routing default in CORE, not just memory.** The eight existing Syncro memories failed to prevent the behavior because only their index lines load each session; CORE rules bind every turn. The Skill-first + Definition-of-Done rules went into `.claude/CLAUDE.md` so they apply fleet-wide every session. +- **Two-half rule: route + gate.** (1) Map the request to a doing-skill; (2) gate the result with the matching check-skill before "done." Both inferred from the request, never user-named. +- **Enforcement tier A+B, defer C (the Stop-hook backstop).** A+B (CORE rule + on-demand map) are cheap and low-risk. The deterministic hook is the only thing that removes reliance on Claude's memory, but carries nag/friction risk ("don't cause more issues"), so it's deferred until the rule+map are proven. Turning it on later is a one-line change; the trigger to do so is catching a skipped gate. +- **On-demand map file, not CORE bloat.** `SKILL_ROUTING.md` holds the full table and is read only when a request maps to a skill or work nears done — keeps CORE lean and costs no tokens until triggered. +- **Calibrate to stakes + Ollama Tier-0.** Trivial edits skip heavy review; security/auth/outbound always get the full gate. Cheap classify/prose passes route to Ollama to keep token cost low (Howard's explicit constraint). +- **Clarified the ambiguous billing memory** rather than deleting it: `feedback_syncro_billing.md` §1 "directly" means "not the timer workflow," not "bypass the skill" — closed the misread that caused the original problem. + +## Problems Encountered + +- **Apparent "lost" `git add`** — after staging the first batch of files, `git status --short` showed only the pre-existing `ampipit` submodule change. Cause: the machine's auto-sync had already committed the edits in commit `5bace24` ("auto-sync from HOWARD-HOME at 2026-06-26 11:40:19"). Verified via `git log -- ` and `git show --stat HEAD`. No data lost; confirmed `## main...origin/main` in sync. +- **Second batch timing** — to avoid relying on the auto-sync timer for the A+B changes, committed and pushed them explicitly. LF→CRLF warnings on the two new/edited files are benign Windows line-ending normalization. + +## Configuration Changes + +Modified: +- `.claude/CLAUDE.md` — added **Skill-first** key rule (use the skill, never hand-roll the API; Syncro billing always via `/syncro`); extended it into a **Definition of Done** (route to doing-skill, gate with matching check-skill before done; calibrate to stakes; Ollama Tier-0; pointer to `SKILL_ROUTING.md`). +- `.claude/memory/feedback_syncro_billing.md` — added clarifying paragraph: run billing THROUGH `/syncro`; §1 "directly" = "not the timer workflow," not "bypass the skill." +- `.claude/memory/MEMORY.md` — added/updated Syncro-section index line for `feedback_skill_first_routing`. +- `errorlog.md` — logged the correction (`--correction`). + +Created: +- `.claude/memory/feedback_skill_first_routing.md` — the Skill-first + Definition-of-Done feedback memory. +- `.claude/SKILL_ROUTING.md` — on-demand request→doing-skill→check-skill routing map. + +## Credentials & Secrets + +None discovered, created, or rotated this session. + +## Infrastructure & Servers + +None touched. (Referenced only in routing examples: Syncro at `computerguru.syncromsp.com`; coord API `http://172.16.3.30:8001/api/coord` — no changes.) + +## Commands & Outputs + +- `bash .claude/scripts/log-skill-error.sh "syncro/billing" "hand-rolled add_line_item API calls from memory instead of using the /syncro skill; ..." --correction --context "rule=skill-first memory=feedback_skill_first_routing tickets=#32193,#32194"` → `[OK] logged skill error to errorlog.md (syncro/billing)` +- `git show --stat HEAD` confirmed auto-sync commit `5bace24` captured the first batch (CLAUDE.md +11, MEMORY.md +1, feedback_skill_first_routing.md +18, feedback_syncro_billing.md +2, errorlog.md +2). +- Second commit (A+B): `harness: add Definition-of-Done skill routing ...` pushed to `origin/main`; `git status -sb` → `## main...origin/main`. + +## Pending / Incomplete Tasks + +- **Option C (deterministic Stop-hook backstop) deferred** — non-blocking hook that reminds when code was edited but no review ran. Turn on if/when a skipped gate is caught in practice. One-line settings.json change via `update-config`. +- Maintain `.claude/SKILL_ROUTING.md` as skills are added/changed (it is the durable map). +- Pre-existing `projects/msp-tools/ampipit` submodule change remains uncommitted — not part of this work; left untouched intentionally. + +## Reference Information + +- CORE rules: `.claude/CLAUDE.md` (Skill-first + Definition of Done under "Key rules (always)"). +- Routing map: `.claude/SKILL_ROUTING.md`. +- Memory: `.claude/memory/feedback_skill_first_routing.md`; related `feedback_syncro_billing`, `feedback_syncro_preview_mandatory`, `feedback_psa_default_syncro`, `feedback_syncro_priority_type_format`, `feedback_impeccable_on_outbound`, `feedback_calibrate_effort_to_stakes`. +- Syncro malformed-ticket precedents Winter flagged: tickets #32193, #32194 (and the priority/type-format memory). +- Auto-sync commit: `5bace24`.