WHAT
Purpose and context
- Purpose: gate every commit — typecheck, lint, test, smoke before commit; after commit promote draft to wiki and close the task lifecycle.
- Trigger (when to use): After any impl task, before
git commit. - Non-goals: do not write new features, do not skip any step because of a "small change", do not change the task state-machine outside the command
code-logger.pyalready declared.
Mental model
diff → typecheck → lint → test → qc-regression → task_lifecycle gate → smoke → commit (why) → promote draft (+ ## Origin) → log + index → task state=done.
Input and output contract
| Field | Required? | Meaning | |
|---|---|---|---|
| In | implemented code changes | yes | gate target |
| In | draft matching the feature in llmwiki/wiki/sources/draft/ |
no | none (hotfix/refactor) → write "no draft — " to the log |
| In | task: T-… in the draft frontmatter |
no | none → skip step 8 (fail-open) |
| Out | commit | yes | message states why, not what |
| Out | promoted wiki page has ## Origin |
when there is a draft | concepts/ or sources/ |
| Out | llmwiki/wiki/log.md + index.md |
yes | update |
Rules and capabilities
- RULE-01 (MUST): All steps mandatory. No exceptions.
- RULE-02 (MUST): Post-commit — mandatory, never skip.
- Capabilities: run the repo's typecheck/lint/test/smoke (auto-detect via manifest); run the validator harness if present; write git commit + wiki + task lifecycle log.
Failure boundaries
- Typecheck/lint/test red → blocked: fix then rerun, do not commit.
qc-regression.py --runred → blocked (bug already fixed has regressed or not yet fixed); no testqc-*→ fail-open, do not block.task_lifecycle.pyblocks (task-ID wrong state-machine) → blocked; no file (old install) → skip.- No draft → do not promote, write the reason to the log (succeeded narrow). No
task:id → skip step 8, not an error.
HOW
Main workflow
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W01 | deterministic | repo | Type-check (detect command per repo) | rc 0 | error → fix, repeat |
| W02 | deterministic | repo | Lint | rc 0, warning note | error → fix, repeat |
| W03 | deterministic | repo | Test + qc-code reproduction test (3b, if harness exists) | rc 0 | fail → fix, repeat |
| W04 | deterministic | draft/task | Pillar 3 gate task_lifecycle.py (if harness exists) |
rc 0 | blocked → blocked |
| W05 | judgment | app | Smoke check golden path end-to-end | golden path runs | broken → fix |
| W06 | effect | diff | Commit, message why | commit hash | — |
| W07 | effect | draft | Promote draft + ## Origin + log + index |
wiki page | no draft → B01 |
| W08 | effect | task: id |
Close task lifecycle via code-logger.py (best-effort) |
state=done | no id → B02 |
Details of each step (source of truth for W01–W08; W01–W03 = steps 1–3b, W04 = 4, W05 = 5, W06 = 6 pre-commit, W07 = 6–7 post-commit, W08 = 8):
Pre-commit:
RUN: <type-check-cmd>— detect from repo:npx tsc --noEmit(package.json) /go build ./...(go.mod). Fix all errors.RUN: <lint-cmd>— detect:npx eslint src//go vet ./.... Fix errors; note warnings.RUN: <test-cmd>— detect:npm test/go test ./.... Fix failures. 3b. qc-code reproduction test (if harness exists):RUN: [ -f harness/scripts/qc-regression.py ] && python3 harness/scripts/qc-regression.py --run— run the testsqc-*generated by/qc-code(reproduce found bugs). RED = a bug that was fixed has now regressed, or is not fixed yet. Deterministic, 0-token, does NOT call LLM. Fail-open if no testqc-*exists yet (project does not use qc-code yet) — do not block.- Pillar 3 gate (if harness exists):
RUN: [ -f harness/validators/task_lifecycle.py ] && python3 harness/validators/task_lifecycle.py --root .— hard block if a task-ID goes through the wrong state-machine (backward/jump/gate-bypass) or the draft points to a foreign task. No file (old install) → skip. This is the HARD version of step 8 best-effort below. - Smoke check: verify golden path end-to-end.
- Commit with message: why, not what.
Post-commit — mandatory, never skip:
6. Find draft in llmwiki/wiki/sources/draft/ matching feature.
- Promote to
llmwiki/wiki/concepts/orllmwiki/wiki/sources/(permanent). - Add
## Originsection:Draft: <path>/Commit: <hash> — <msg>/Date: YYYY-MM-DD CHECK: grep -l "## Origin" <promoted-file>— must return file.
RUN: echo "promoted" >> llmwiki/wiki/log.md— then edit log properly; updatellmwiki/wiki/index.md.- Pillar 3 — close lifecycle (best-effort, fail-open): draft has frontmatter
task: T-…→python3 harness/scripts/code-logger.py --task set <T-id> state=done note="<commit-hash>". Fail-open command (missing--task/id → skip, do not block commit). Confirm:--task show <T-id>in lifecycle proposed→approved→dispatched→done;--auditverify the transitions lie within the invariant chain.
No draft (hotfix/refactor)? Note "no draft — " in log.md, skip step 6. No
task:id (old install / propose skipped mint)? Skip step 8 — fail-open, not an error.
All steps mandatory. No exceptions.
Branches
| ID | Kind | Guard | Behavior | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | conditional_required | no draft (hotfix/refactor) | write "no draft — " into log.md, skip step 6 post-commit |
— | W08 |
| B02 | conditional_required | draft has no task: id (old install / propose skipped mint) |
skip step 8 — fail-open | — | end |
| B03 | capability_optional | has harness/ (qc-regression, task_lifecycle, code-logger) |
run 3b, 4, 8 | missing file → skip, fail-open | next step |
Validation and stopping
Deterministic: rc of typecheck/lint/test/qc-regression/task_lifecycle; CHECK: grep -l "## Origin" <promoted-file> must return files; --task show <T-id> + --audit confirm lifecycle. Needs review: smoke golden path. Stop when all pre + post steps are done; red at pre-commit means no commit.
Examples
- Positive: repo has
package.json→npx tsc --noEmit,npx eslint src/,npm testgreen,qc-regression.py --rungreen → commit "why" → promote draftDDMMYY-login-otp.mdintowiki/concepts/has## Origin→code-logger.py --task set T-12 state=done note="<hash>". - Boundary/failure:
go test ./...1 test fails → stop at W03, fix and rerun, not yet committed. Hotfix has no draft → log "no draft — hotfix typo", skip promote.
Delivery — Output Report
After all main skill tasks complete, write a propose draft to the wiki.
Steps
1. Build the filename:
- Format:
DDMMYY-<ten>.md DDMMYY= today (e.g.,020626for 2 June 2026)<ten>= 2–4 kebab-case words summarising what was done (e.g.,landing-page-coteccons,brand-kit-fintech,ingest-auth-spec)
2. Write llmwiki/wiki/sources/draft/DDMMYY-<ten>.md:
---
type: draft
title: "DDMMYY-<ten>"
status: proposed
tags: [<skill-name>, output-report]
timestamp: YYYY-MM-DD
---
# DDMMYY-<ten>
**Type:** draft
**Status:** proposed
**Tags:** <skill-name>, output-report
**Proposed:** YYYY-MM-DD
## What
<One sentence — what this skill invocation produced or decided>
## Output
<Key artefacts, files created/modified, or decisions made>
## Files
| File | Action |
|------|--------|
| `path/to/file` | created / modified |
## Notes
- Invoked via: `/<skill-name>` skill
## Origin
- **Draft:** `wiki/sources/draft/DDMMYY-<ten>.md`
- **Commit:** _(filled by verify-before-commit)_
- **Date promoted:** _(filled by verify-before-commit)_
3. Update wiki index & log:
llmwiki/wiki/index.md— append one row:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |llmwiki/wiki/log.md— append:## YYYY-MM-DD — <skill-name> — <ten>
Skip only when the skill produces zero artefacts and zero decisions (e.g., a pure display mode like
/caveman-stats).