Purpose
hstack-commit is the human-driven commit Skill that matches the Commitizen format hstack subagents use for their auto-commits. The point is uniform git history: a reader scanning the log cannot tell whether a given commit was a subagent auto-commit or a human-typed one, because both follow <type>(<scope>): <summary>. It does not replace the kernel's auto-commit-at-status-transition rule — subagents still auto-commit on their own. The Skill is for everything else: typo fixes, ad-hoc cleanups, edits between hstack invocations, the occasional manual touch.
When to invoke
Invoke when:
- You've made an edit by hand (outside a hstack subagent flow) and want to commit it.
- You want to commit work-in-progress before stepping away.
- A subagent auto-commit didn't fire (rare, but possible if a Skill halted mid-phase) and you need to capture state manually.
Do NOT invoke inside an hstack subagent flow — the subagents auto-commit on status transitions per the kernel.
Inputs
- No positional arguments. The Skill drives entirely from
git statusand conversation. - Optional
--pushflag: if set, push after committing (still subject to explicit per-invocation confirmation; the system never force-pushes).
Preconditions
Before any work:
- Verify the working directory is a git repository.
- Read
hstack/config.yamlif present, to namespace the commit scope when committing inside an hstack-governed repo. Absent config is fine — the Skill works on any repo, hstack-installed or not. - Verify there are changes to commit. If working tree is clean, halt with "nothing to commit."
Orchestration steps
Read git status. Run
git status --shortand show the file list with their status markers. Categorize: modified, untracked, deleted, renamed.Stage with intent. Default to staging by named path, NOT
git add -A. The latter sweeps in.env, credentials, large binaries, and other unintended files. The Skill proposes the specific files to stage based on the change being committed, the engineer confirms.- Exception: if every file is clearly part of one logical change AND none of the file names match common sensitive patterns (
.env,secret,credential,*.key,*.pem), the Skill may proposegit add -Awith the engineer's explicit confirmation. - Sensitive-file guardrail: if any staged file's name matches the sensitive-pattern list, halt and ask before committing.
- Exception: if every file is clearly part of one logical change AND none of the file names match common sensitive patterns (
Show the diff. Run
git diff --cached --statfor a summary, thengit diff --cachedfor the full diff if the diff is reasonably small. For large diffs, show stat plus a sample of the most-changed files.Draft a Commitizen-format commit message. Following the format codified for hstack:
- Format:
<type>(<scope>): <summary> <type>is one of:feat,fix,chore,docs,refactor,test,style,perf,ci<scope>names the area being touched. For commits inside hstack-governed code, prefer the change-id, the area, the Skill name, or the artifact type (e.g.,change-plan,billing,implement,data-review). For non-hstack commits in the same repo, use the natural area (e.g.,auth,orchestrator,webhooks).<summary>≤ 72 characters, imperative present tense ("add" not "added"), no trailing period.- Body (optional): the "why" rather than the "what". For commits inside hstack workflow, name the related change-id or artifact. For status transitions, name the transition explicitly.
- Never add "Generated with Claude Code" or similar attribution. The user's global rule.
- Footer: only conventional-commits footers (
BREAKING CHANGE:,Refs: <issue>) when applicable.
- Format:
Confirm and commit. Show the proposed commit message to the engineer. On confirmation, run
git commit -m "<subject>" -m "<body>"(HEREDOC for multi-line bodies). Honor every git hook —--no-verify,--no-gpg-sign, and other bypass flags are forbidden.Verify the commit landed. Run
git log -1 --format='%h %s'and surface the result.Push (only with explicit confirmation). Push is hard-to-reverse and visible to others — never auto-push. If
--pushwas provided, ask for confirmation in the conversation; if not provided, end without pushing. When pushing, use the current branch's tracked upstream (no--force, no force-with-lease without per-invocation authorization, no push tomainif the current branch ismainwithout explicit confirmation).
Outputs
- One git commit on the current branch.
- Optionally, a
git pushto the current branch's upstream — but only with explicit per-invocation confirmation. - No artifact writes. No subagent invocations.
Auto-commit triggers
None. This Skill IS the commit — there is nothing else for it to auto-commit. Subagents have their own auto-commit logic governed by the kernel.
Idempotency contract
Not idempotent in the strict sense — a commit is a one-shot operation. Re-running the Skill on a clean working tree halts with "nothing to commit," which is the natural idempotency boundary.
Stop conditions
Beyond the kernel's general stop conditions:
- Working tree is clean. Nothing to commit.
- A staged file's name matches the sensitive-pattern list (
.env,*secret*,*credential*,*.key,*.pem). Halt and ask. - A pre-commit hook fails. Investigate and fix the underlying issue — do NOT bypass with
--no-verify. If the fix requires out-of-scope edits (when committing inside an hstack-governed change), halt and surface as a scope-amendment situation. - The proposed commit message exceeds 72 characters on the summary line. Re-draft.
- A destructive push operation is requested (
--force, force-with-lease, push tomain) without explicit per-invocation authorization in the current conversation. Halt and confirm. - The engineer requested
--pushbut the current branch has no upstream. Halt and ask which remote / branch to push to.
Failure modes
- Pre-commit hook fails. Investigate; surface the hook's output; propose a fix. Re-run the commit attempt with the fix in place. Never bypass.
gpg-signconfigured but signing key unavailable. Surface the gpg error; do NOT bypass with--no-gpg-sign. Engineer fixes their gpg config and re-runs.git pushrejected (non-fast-forward). Surface the rejection; recommendgit pull --rebasethen re-attempt; never propose--forcewithout explicit authorization.- Empty commit attempted. If
git addleft the index empty (e.g., every staged change was already committed), halt with the empty-commit message; do not use--allow-emptywithout engineer confirmation.
Anti-patterns
- Never use
git add -Asilently. Default to staging by named path; sweep only with explicit engineer confirmation. - Never use
--no-verify,--no-gpg-sign, or any hook-bypass flag. - Never use
git commit --amendto modify a published (pushed) commit without explicit per-invocation authorization. The system prompt's safety rule applies. - Never auto-push. Push is a separate, explicit, per-invocation decision.
- Never use
git push --forceor--force-with-leasewithout explicit per-invocation authorization in the current conversation. - Never add "Generated with Claude Code" or any AI-attribution footer to the commit message. The user's global rule forbids it.
- Never invent a
<scope>that doesn't reflect what was actually touched. If the change spans multiple unrelated areas, propose splitting into multiple commits. - Never commit a file whose name matches the sensitive-pattern list without explicit engineer confirmation.
- Never bypass the kernel's database-workflow or forbidden-tools rules even when committing manually —
service_rolekeys,supabase db pushagainst remote, etc., are forbidden regardless of the commit path.
Source: hugoganet/hstack — distributed by TomeVault.