@ok-ggwp/git-gloss 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@ok-ggwp/git-gloss",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Annotate agent-written diffs with intent and necessity, stored in git notes",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "git",
8
+ "notes",
9
+ "code-review",
10
+ "ai",
11
+ "agents",
12
+ "annotations"
13
+ ],
14
+ "homepage": "https://github.com/ok-ggwp/git-gloss#readme",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/ok-ggwp/git-gloss.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/ok-ggwp/git-gloss/issues"
21
+ },
22
+ "type": "module",
23
+ "bin": {
24
+ "git-gloss": "bin/git-gloss.js"
25
+ },
26
+ "files": [
27
+ "bin",
28
+ "dist",
29
+ "skills",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "engines": {
34
+ "node": ">=20.12"
35
+ },
36
+ "scripts": {
37
+ "build": "node scripts/build.mjs",
38
+ "prepare": "npm run build",
39
+ "test": "node --test 'test/**/*.test.ts'",
40
+ "typecheck": "tsc"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "dependencies": {
46
+ "zod": "^4.6.7"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^26.6.5",
50
+ "typescript": "^7.0.2"
51
+ }
52
+ }
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: gloss
3
+ description: Annotate changes with their intent and necessity using git-gloss, so reviewers and later agents can see why each change exists. The default is the wip-gloss procedure: gloss uncommitted work before reporting back, so the user can read and review it before committing. Use after a non-trivial code change in a repo whose CLAUDE.md or AGENTS.md asks for wip-gloss, when the user asks to "gloss" or "wip-gloss" changes or a commit, or before handing changes off for review. Also use `git gloss why <file>:<start>-<end>` when genuinely unsure why existing code is the way it is, such as before removing something that looks unnecessary.
4
+ ---
5
+
6
+ # Glossing changes (wip-gloss)
7
+
8
+ A gloss records, for each part of a change, what it does, how necessary it is, and what breaks without it. You are writing it while you still have the context of why you made each change. That context is the point: do not just restate the diff.
9
+
10
+ ## The wip-gloss procedure
11
+
12
+ In a repo whose `CLAUDE.md` or `AGENTS.md` asks for it (set up with `git gloss init --hooks`), when you finish a non-trivial code change, wip-gloss it before reporting back:
13
+
14
+ 1. Leave the changes uncommitted; don't commit unless the user asks.
15
+ 2. Gloss them with the steps below (`git gloss hunks wip`, `add wip`, `show wip`).
16
+ 3. In your reply, say that the changes are wip-glossed and how to read them (`git gloss show wip`, or `git gloss html wip --open`), and mention anything you graded `speculative`, `incidental` or `defensive`: those are the parts the user may want to drop.
17
+ 4. When the user or a reviewer asks for changes, make them, then run `git gloss hunks wip` and `git gloss add wip` again. The new snapshot keeps the gloss of unchanged groups (`hunks wip` says how many) as a placeholder; write the full gloss again, which replaces it. A gloss must describe the code as it is now.
18
+ 5. Committing is the user's call; see below for how the gloss moves onto the commit.
19
+
20
+ Skip it for trivial edits (a typo, a one-line config tweak) unless asked.
21
+
22
+ ## Uncommitted work (the default) or a commit
23
+
24
+ Gloss changes **before they are committed**, unless the user asks you to commit first. `wip` stands for a snapshot of the uncommitted work (tracked and untracked files): `git gloss hunks wip` takes it without touching the branch, the index or any file, and the other commands then use that snapshot. The user reviews and iterates while nothing is committed. When they commit, the gloss moves onto the commit automatically if `git gloss init --hooks` was run and `git gloss` is on the PATH of whatever runs the commit; otherwise they run `git gloss adopt`. Glosses of uncommitted work are never shared by `sync`. Untracked files that look like secrets (`.env`, keys, credentials) are left out of the snapshot with a note; don't stage them just to gloss them.
25
+
26
+ To gloss a commit instead, use its revision (default `HEAD`) wherever these steps say `wip`.
27
+
28
+ ## Steps
29
+
30
+ 1. Run `git gloss hunks wip` to snapshot the uncommitted work and see it split into hunks with ids `h1`, `h2`, …, with each hunk's changed (`+`/`-`) lines numbered from 1. If you change files afterwards, run it again: that takes a new snapshot, and a gloss must match the snapshot it was written for.
31
+ 2. Group changes **by intent**, not by file. One intent often spans several files. When one hunk mixes intents (common in new files, which are a single hunk), give each group only its lines: `"h6:1-40"`, `"h6:41-55,60"`. The numbers count changed lines only, as `hunks` prints them. Every changed line must belong to at least one group; `add` lists any that don't.
32
+ Take hunk ids and line numbers from the `git gloss hunks` output for this snapshot or commit, never from memory of the diff or from an earlier commit. Ids depend on the order git lists hunks, and line numbers count only changed lines, so guesses are easily wrong. `add` rejects ranges past the end of a hunk, but a wrong range that stays in bounds is accepted and silently attaches an intent to the wrong code.
33
+ 3. Write the annotation JSON (shape below; `git gloss schema` prints the full JSON Schema) to a file in your scratchpad, then run:
34
+ `git gloss add wip -f <file>`
35
+ Fix any validation errors it reports and rerun. Use `--force` only to replace your own earlier gloss.
36
+ 4. Run `git gloss show wip` (the summary) and `git gloss show wip --full` (every group's details) and check that they read well to someone who was not in the session. Then spot-check the code under a few groups with `git gloss show wip -g <group>`. Validation checks that every line is covered, not that each line is under the right intent.
37
+
38
+ If you edit files after glossing, `show wip` warns that the working tree has changed: run `git gloss hunks wip` again and re-gloss with `--force`. If you amend or rebase a glossed commit, the hooks from `git gloss init --hooks` carry the gloss along (and combine glosses on squash and fixup); if `show` still reports it stale or missing, run `git gloss carry --find --squash` before re-glossing by hand with `--force`. A replaced gloss is never lost: `git gloss versions <commit>` lists them. For a review of the uncommitted work, the user can run `git gloss review wip`, or `git gud review wip` to have agents review it in a sandbox.
39
+
40
+ ## Writing intents
41
+
42
+ `show` lists one row per group, so keep each `intent` to one short sentence (under ~80 characters) saying what the group does. Put mechanism, caveats and history in `notes`. `add` prints a note for intents over 100 characters.
43
+
44
+ ## Grading necessity honestly
45
+
46
+ Self-grading tends to call everything "required". Resist that. Use these categories:
47
+
48
+ - `required`: the task cannot be done without it.
49
+ - `supporting`: needed only because other groups need it. Set `serves` to that group's id, or a list of ids.
50
+ - `mechanical`: follow-on edits with no design content (renames, imports, formatting, lockfiles). Keep these short.
51
+ - `incidental`: a drive-by cleanup or refactor the task did not ask for.
52
+ - `defensive`: guards edge cases or failures nobody asked about.
53
+ - `speculative`: added because it might be useful later.
54
+
55
+ Test each group with "what concretely breaks if this is removed?" and write the answer in `removal_impact`. Name the specific loss, even for tests and docs: "the merge-base conflict rule would have no test", not "Unverified"; "users wouldn't know `--rev` exists", not "Undocumented". If the honest answer is "nothing the task needs", the group is `incidental`, `defensive` or `speculative`. Saying so is the useful outcome; it tells the reviewer what can be dropped.
56
+
57
+ Tests are `supporting`, with `serves` listing every group they verify: `"serves": ["retry-core", "retry-config"]`. The same goes for a shared helper that several groups need. Groups the tests cover can cite them in `evidence`.
58
+
59
+ Documentation has no category of its own; grade it by why it changed. Docs for a feature or behaviour change in the same change are `supporting`, with `serves` set to that group. Docs that are themselves the task are `required`. Typos, reflowing and renames are `mechanical`; unrelated doc improvements are `incidental`; documenting something that doesn't exist yet is `speculative`. Agent instructions (a skill, `CLAUDE.md`, `AGENTS.md`) change what agents do, so grade them like behaviour, not as `mechanical`.
60
+
61
+ Where you can, set `evidence` to a test that exercises the change or the line of the task that requires it.
62
+
63
+ ## Annotation shape
64
+
65
+ ```json
66
+ {
67
+ "task": "Retry uploads on transient 5xx errors (from the user's request)",
68
+ "summary": "Wraps the upload call in exponential backoff and exposes the retry count.",
69
+ "groups": [
70
+ {
71
+ "id": "retry-core",
72
+ "intent": "Retry the upload with exponential backoff on 5xx",
73
+ "necessity": "required",
74
+ "serves": "task",
75
+ "removal_impact": "Uploads fail on the first 503",
76
+ "evidence": "test/upload.test.ts 'retries on 503'",
77
+ "hunks": ["h1", "h3:1-12"]
78
+ },
79
+ {
80
+ "id": "retry-config",
81
+ "intent": "Make max retries configurable",
82
+ "necessity": "speculative",
83
+ "serves": "retry-core",
84
+ "removal_impact": "Retry count would be a hardcoded 3; nothing in the task needs it configurable",
85
+ "hunks": ["h2"]
86
+ }
87
+ ],
88
+ "alternatives": [
89
+ { "option": "Retry inside the HTTP client", "rejected_because": "Would also retry non-idempotent calls" }
90
+ ],
91
+ "risks": ["Duplicate uploads if the server is not idempotent"],
92
+ "author": { "agent": "claude-code", "model": "<your model id>" }
93
+ }
94
+ ```
95
+
96
+ `alternatives` and `risks` are optional, but fill them in when you weighed real options. They are what later readers most often lack.
97
+
98
+ ## Looking up intent
99
+
100
+ You don't need to look up intent before ordinary edits. Use `git gloss why` when you are genuinely unsure why existing code is the way it is, especially before removing or rewriting something that looks unnecessary, defensive or wrong. That is when an unexplained check gets deleted and a fixed bug comes back.
101
+
102
+ Ask about the block you're changing, not each line: `git gloss why <file>:<start>-<end> --json`. You get one explanation per commit that last changed those lines: the group's intent, `removal_impact`, `notes`, and the commit's `risks` and rejected `alternatives`. Check the alternatives before proposing an approach someone already tried and turned down. If the latest change to the lines was only `mechanical` (a rename, a reformat), `why` looks back past it to the real explanation; `--history` shows every change.
103
+
104
+ ## Reading someone else's branch
105
+
106
+ When the user asks you to help review a branch or pull request, start from its glosses: `git fetch` (or `git gloss sync`), then `git gloss show <base>..<branch>`. You get each commit's task, groups and grades, and whether its gloss was honesty-reviewed. Lead with what the glosses grade `speculative`, `incidental` or `defensive`, and with commits that have no gloss or whose review found issues. `git gloss reviews <base>..<branch>` prints the recorded findings. A review vouches only for the gloss and code it saw: "changed since review" means it no longer does.