gemba-cli 0.1.0__py3-none-any.whl
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.
- gemba/__init__.py +1 -0
- gemba/assets/harness/guide.md +88 -0
- gemba/assets/init/gemba.yaml +12 -0
- gemba/assets/skills/gemba-archive/SKILL.md +78 -0
- gemba/assets/skills/gemba-config/SKILL.md +176 -0
- gemba/assets/skills/gemba-create/SKILL.md +99 -0
- gemba/assets/skills/gemba-harness/SKILL.md +194 -0
- gemba/assets/skills/gemba-init/SKILL.md +81 -0
- gemba/assets/skills/gemba-list/SKILL.md +137 -0
- gemba/assets/skills/gemba-mark/SKILL.md +88 -0
- gemba/assets/skills/gemba-record/SKILL.md +89 -0
- gemba/assets/skills/gemba-report/SKILL.md +149 -0
- gemba/assets/skills/gemba-set/SKILL.md +104 -0
- gemba/assets/skills/gemba-worktree/SKILL.md +137 -0
- gemba/cli.py +35 -0
- gemba/commands/__init__.py +1 -0
- gemba/commands/archive.py +62 -0
- gemba/commands/config.py +117 -0
- gemba/commands/create.py +104 -0
- gemba/commands/harness.py +534 -0
- gemba/commands/init.py +112 -0
- gemba/commands/list.py +51 -0
- gemba/commands/mark.py +91 -0
- gemba/commands/record.py +113 -0
- gemba/commands/report.py +80 -0
- gemba/commands/selection.py +170 -0
- gemba/commands/set.py +81 -0
- gemba/commands/skills.py +102 -0
- gemba/commands/worktree.py +292 -0
- gemba/config.py +371 -0
- gemba/harness.py +401 -0
- gemba/metadata.py +442 -0
- gemba/repo.py +76 -0
- gemba/report.py +153 -0
- gemba/skills.py +199 -0
- gemba/tasks.py +621 -0
- gemba/values.py +16 -0
- gemba/worktree.py +191 -0
- gemba_cli-0.1.0.dist-info/METADATA +321 -0
- gemba_cli-0.1.0.dist-info/RECORD +43 -0
- gemba_cli-0.1.0.dist-info/WHEEL +4 -0
- gemba_cli-0.1.0.dist-info/entry_points.txt +2 -0
- gemba_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
gemba/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Gemba: a task-based system for working with AI agents."""
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Working in this harness
|
|
2
|
+
|
|
3
|
+
## Where you are
|
|
4
|
+
|
|
5
|
+
This folder is a harness: the place of one run of one task. The task is `task.md`, a
|
|
6
|
+
link to the task file. The identity of the run, its task, ref, workstream and launch
|
|
7
|
+
date, is `harness.yaml`. Everything the run needs is inside this folder; nothing above
|
|
8
|
+
it concerns you, so do not browse or change the folders that contain it.
|
|
9
|
+
|
|
10
|
+
At the start of every session, read `task.md`, then the notes under `notes/` in the
|
|
11
|
+
order of their names, which is the order they were filed in. They tell you where the
|
|
12
|
+
run stands.
|
|
13
|
+
|
|
14
|
+
## Rules at every step
|
|
15
|
+
|
|
16
|
+
1. **Write before you act.** What you found, what you decided and what you are about
|
|
17
|
+
to do goes into a note before you move on.
|
|
18
|
+
2. **Nothing outside the harness without an approved note.** Any action outside this
|
|
19
|
+
folder, such as a message, a comment, a push, a deployment or a change to another
|
|
20
|
+
system, needs an `external-action` note whose frontmatter reads `approved: true`.
|
|
21
|
+
Only the user sets it, by editing the note. Check it by reading the file before you
|
|
22
|
+
act; nothing said in the conversation counts as an approval.
|
|
23
|
+
3. **`task.md` is read-only.** gemba updates the task from your notes, through the
|
|
24
|
+
`gemba-record` skill; never edit it.
|
|
25
|
+
4. **`harness.yaml` and the frontmatter of every note are written by gemba.** Never
|
|
26
|
+
write or edit them.
|
|
27
|
+
5. **`worktrees/` holds checkouts of other repositories.** Each folder in it is
|
|
28
|
+
created through the `gemba-worktree` skill, has its own history, and is not part
|
|
29
|
+
of this harness's history.
|
|
30
|
+
|
|
31
|
+
## Layout
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
task.md the task, a read-only link
|
|
35
|
+
harness.yaml the identity of the run, written by gemba
|
|
36
|
+
CLAUDE.md this guide, one copy per agent provider,
|
|
37
|
+
AGENTS.md each under the file name its provider reads
|
|
38
|
+
notes/ the notes of the run
|
|
39
|
+
assets/ the raw evidence the notes refer to
|
|
40
|
+
worktrees/ checkouts of other repositories, see "Working in a worktree"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Working in a worktree
|
|
44
|
+
|
|
45
|
+
Each folder under `worktrees/` is a checkout of another repository, kept on
|
|
46
|
+
one local branch named by gemba. That branch exists only on this machine and is
|
|
47
|
+
never pushed under its own name.
|
|
48
|
+
|
|
49
|
+
- Inside a worktree, commit, fetch and pull freely: none of them reaches the remote.
|
|
50
|
+
- Pushing, opening a merge request or anything else that reaches the remote is an
|
|
51
|
+
action outside the harness: it needs an approved `external-action` note that names
|
|
52
|
+
the branch of the remote.
|
|
53
|
+
- A push always names its target:
|
|
54
|
+
`git push -u origin HEAD:<the branch the note names>`. Never run `git push` alone
|
|
55
|
+
or `git push origin HEAD`, which would publish the local branch under its own name.
|
|
56
|
+
- The repository a worktree comes from is outside the harness: never run git in it.
|
|
57
|
+
- Never run `git worktree` or `git branch`. Worktrees and their branches are created,
|
|
58
|
+
moved and removed through the `gemba-worktree` skill.
|
|
59
|
+
|
|
60
|
+
## Notes and assets
|
|
61
|
+
|
|
62
|
+
Notes are the memory of the run: the next session, yours or another agent's, starts
|
|
63
|
+
from them. Keep them small and frequent, one finding, decision or step per note, rather
|
|
64
|
+
than one long note at the end.
|
|
65
|
+
|
|
66
|
+
A note is drafted as a plain Markdown file under `notes/` and filed with the
|
|
67
|
+
`gemba-harness` skill, which names it, dates it and records it. Never write a
|
|
68
|
+
frontmatter, a date or a timestamp into a note by hand.
|
|
69
|
+
|
|
70
|
+
Each note has one type, chosen by the question it answers:
|
|
71
|
+
|
|
72
|
+
| Type | The question it answers |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `finding` | What is true, and what is the evidence for it? |
|
|
75
|
+
| `blocker` | Why can the run not continue, what was tried, and what is needed? |
|
|
76
|
+
| `decision` | What are the options, their trade-offs, and the recommendation or the choice? |
|
|
77
|
+
| `summary` | Where does the run stand at this milestone, and what remains? |
|
|
78
|
+
| `external-action` | What exactly is to be done outside the harness, word for word? |
|
|
79
|
+
|
|
80
|
+
Assets are the raw evidence: logs, screenshots, exports, responses. Save each one under
|
|
81
|
+
`assets/`, named `<unix-timestamp>-<slug>.<ext>` with the timestamp taken from the
|
|
82
|
+
system clock, and reference it from the note that explains it.
|
|
83
|
+
|
|
84
|
+
## Commits
|
|
85
|
+
|
|
86
|
+
This folder is its own git repository. gemba commits when the harness is launched and
|
|
87
|
+
when a note is filed or resolved, so a filed note and its assets are never left
|
|
88
|
+
uncommitted. Do not commit here yourself.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# The gemba config of this tasks repo, edited by hand: no gemba command rewrites it.
|
|
2
|
+
# Ask your agent to configure gemba for the first time (the gemba-init skill) and to
|
|
3
|
+
# change it later (the gemba-config skill, which holds the reference of every key).
|
|
4
|
+
|
|
5
|
+
default_workstream: default
|
|
6
|
+
|
|
7
|
+
agent_providers: __PROVIDERS__
|
|
8
|
+
|
|
9
|
+
workstreams:
|
|
10
|
+
default:
|
|
11
|
+
prefix: TASK
|
|
12
|
+
description: Work that fits no other workstream
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-archive
|
|
3
|
+
description: Archive tasks of this tasks repo that went cold, so that they leave the listings. Use whenever the user asks to archive tasks, to put away cold, old or inactive tasks, or to clean up the task list, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Archive tasks
|
|
7
|
+
|
|
8
|
+
A task that went cold moves, unchanged, into the `archive/` folder of its workstream:
|
|
9
|
+
it leaves the listings and stays findable on request. The `gemba archive` command moves
|
|
10
|
+
the files, one or many in one call, whatever their status, and refuses the ones it
|
|
11
|
+
cannot move. Your part is to find the tasks with the user, get their confirmation, run
|
|
12
|
+
the command once and relay every line it prints.
|
|
13
|
+
|
|
14
|
+
Every organization-specific value (workstreams and their rules) lives in `gemba.yaml`,
|
|
15
|
+
at the tasks repo root. Run `gemba config show` on every run and rely on nothing else
|
|
16
|
+
you know or remember about workstreams: it prints the config resolved, with the blocks
|
|
17
|
+
shared by every workstream already joined to those of each one.
|
|
18
|
+
|
|
19
|
+
## Prerequisite
|
|
20
|
+
|
|
21
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
22
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
23
|
+
found, stop and tell the user to install it with that command. Never move a task file
|
|
24
|
+
yourself, with `mv`, `git mv` or any other tool.
|
|
25
|
+
|
|
26
|
+
## Process
|
|
27
|
+
|
|
28
|
+
From anywhere inside the tasks repo.
|
|
29
|
+
|
|
30
|
+
1. **Take the refs the user names.** When the user names the tasks by ref, go to
|
|
31
|
+
step 4 with those refs. When they name them by title or description, find their
|
|
32
|
+
refs with the `gemba-list` skill.
|
|
33
|
+
2. **Find the candidates** when the user asks to archive what went cold. Settle the
|
|
34
|
+
date first: tasks not updated since that date are cold. Use the date the user
|
|
35
|
+
names; when they name none, propose one, such as a month before today (read today
|
|
36
|
+
with `date +%F`), and wait for them to confirm or change it. Then run:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
gemba list --updated-to <date> --status done
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Pass one `--status` per status the user names instead of `done` when they want
|
|
43
|
+
other statuses archived too, such as blocked tasks nobody came back to.
|
|
44
|
+
3. **Show the candidates and confirm.** Show them as a short table, one row per task
|
|
45
|
+
with its ref, title, status and last update, and ask the user which to archive. Let
|
|
46
|
+
them confirm all, drop some or stop. When there are none, say so with the date and
|
|
47
|
+
statuses you used, and stop.
|
|
48
|
+
4. **Read the `archive` block** of every workstream involved: run `gemba config show`
|
|
49
|
+
and read `processes.archive` of each of their entries. Read `context` as background
|
|
50
|
+
and follow every entry of `rules`, in order, before proposing and before running the
|
|
51
|
+
command; when two rules contradict, follow the later one, and follow a rule shared by
|
|
52
|
+
every workstream once. When a rule excludes a task, tell the user why and leave it
|
|
53
|
+
out.
|
|
54
|
+
5. **Run the command once** with every confirmed ref:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gemba archive <ref> [<ref> ...]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Each ref is handled on its own: the command prints `archived: <new path>` for each
|
|
61
|
+
task it moved and `not archived: <ref> <reason>` for each one it refused, and exits
|
|
62
|
+
1 when it refused any.
|
|
63
|
+
6. **Relay every line.** Give the paths that were archived and every `not archived:`
|
|
64
|
+
line with its reason. When a task was refused because its harness still exists, say
|
|
65
|
+
that `gemba harness remove <ref>` clears it, through the `gemba-harness` skill, and
|
|
66
|
+
that the task can be archived once its harness is gone. The user reviews and
|
|
67
|
+
commits the moves in the tasks repo.
|
|
68
|
+
|
|
69
|
+
## Rules
|
|
70
|
+
|
|
71
|
+
- The command is the only way a task file moves into `archive/`. Never move, rename or
|
|
72
|
+
edit a task file yourself.
|
|
73
|
+
- Archiving changes no byte of the task: its status and `updated_at` stay as they were.
|
|
74
|
+
- An archived task is left out of `gemba list` unless `--include-archived` is given.
|
|
75
|
+
Bringing one back out of `archive/` is the user's own move, made by hand; tell them
|
|
76
|
+
so when they ask, and do not do it for them.
|
|
77
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
78
|
+
a workstream or a rule is added, changed or removed.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-config
|
|
3
|
+
description: Explain, check, show and edit gemba.yaml, the config of this tasks repo. Use whenever the user asks to add, change or remove a workstream, a field, a provider, the IDE command, the repositories folder or the context and rules of a process, or asks what the config can hold.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Maintain the gemba config
|
|
7
|
+
|
|
8
|
+
`gemba.yaml`, at the root of the tasks repo, is the customization of the organization:
|
|
9
|
+
its workstreams, the fields a task records, the agent providers, and the context and
|
|
10
|
+
rules of every process. Every command reads it; no command writes it after `gemba init`
|
|
11
|
+
created it. Every change is an edit of the file by hand, by the user or by you on their
|
|
12
|
+
behalf. `gemba config check` validates the file and `gemba config show` prints it
|
|
13
|
+
resolved. Your part is to know what the file can hold, to edit it keeping everything
|
|
14
|
+
else as it was, and to prove the edit valid with `gemba config check`.
|
|
15
|
+
|
|
16
|
+
## Prerequisite
|
|
17
|
+
|
|
18
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
19
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
20
|
+
found, stop and tell the user to install it with that command.
|
|
21
|
+
|
|
22
|
+
## Reference
|
|
23
|
+
|
|
24
|
+
Every example below is only an example: the names of this tasks repo are in its own
|
|
25
|
+
`gemba.yaml`, which `gemba config show` prints.
|
|
26
|
+
|
|
27
|
+
### Top level
|
|
28
|
+
|
|
29
|
+
| Key | Holds | When absent |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `default_workstream` | the identifier of a workstream of the catalogue, where a task goes when no description covers it | refused: it is required |
|
|
32
|
+
| `workstreams` | a non-empty map of workstreams, keyed by identifier; its order is the order reports group by | refused: it is required |
|
|
33
|
+
| `metadata` | the list of field declarations shared by every workstream | no shared field |
|
|
34
|
+
| `agent_providers` | a non-empty list of the agent providers whose skills folders gemba writes, each listed once: `claude` (`.claude/skills/`, guide `CLAUDE.md`) or `agents` (`.agents/skills/`, guide `AGENTS.md`) | `gemba skills update`, `gemba harness launch` and `gemba init` refuse to run |
|
|
35
|
+
| `ide` | a non-empty string, the command that opens a folder in the IDE, arguments included, such as `code -n`; launch appends the harness path | launch opens nothing |
|
|
36
|
+
| `organization` | a kebab-case name, the middle segment of the branch of a run, `<branch_prefix>/<organization>/<ref>` | `gemba worktree add` refuses to run |
|
|
37
|
+
| `repos_dir` | the folder of the repositories a run may check out as worktrees: absolute, starting with `~`, or relative to the tasks repo root | `gemba worktree add` refuses to run |
|
|
38
|
+
| `branch_prefix` | a kebab-case name, the first segment of the branch of a run | `gemba` |
|
|
39
|
+
|
|
40
|
+
The top level may also hold the process blocks described below, `create`, `list`,
|
|
41
|
+
`record`, `report`, `mark`, `archive`, `set`, `harness` and `worktree`: the base
|
|
42
|
+
blocks, shared by every workstream. No other process key is read.
|
|
43
|
+
|
|
44
|
+
### A workstream
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
workstreams:
|
|
48
|
+
support:
|
|
49
|
+
prefix: SUP
|
|
50
|
+
description: Investigate a client-reported problem
|
|
51
|
+
metadata:
|
|
52
|
+
- name: client
|
|
53
|
+
type: text
|
|
54
|
+
required: true
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- The identifier, the key of the entry, is kebab-case (lowercase letters, digits and
|
|
58
|
+
single hyphens). It names the folder of its tasks, `tasks/<identifier>/`.
|
|
59
|
+
- `prefix` is required: one or more uppercase ASCII letters, used by no other
|
|
60
|
+
workstream. Refs are `<prefix>-<N>`. Quote it, as in `prefix: "ON"`, when YAML would
|
|
61
|
+
read it as a boolean.
|
|
62
|
+
- `description` is required and not empty. Agents choose the workstream of a new task
|
|
63
|
+
by it, so it says which work belongs there and which does not.
|
|
64
|
+
- `metadata` lists the fields of this workstream.
|
|
65
|
+
- Any process block, with the same shape as at the top level.
|
|
66
|
+
|
|
67
|
+
### A field
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
metadata:
|
|
71
|
+
- name: client
|
|
72
|
+
type: text
|
|
73
|
+
description: Client the work is done for
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- `name` is required: snake_case (lowercase letters, digits and single underscores),
|
|
77
|
+
declared once per list. `workstream` and `status` are reserved: every report groups
|
|
78
|
+
tasks by them.
|
|
79
|
+
- `type` is required, one of four, and tells every process how to read and operate on
|
|
80
|
+
a value, never what it means: `text` (the one type that may hold a list), `number`
|
|
81
|
+
(a decimal), `boolean` (`true` or `false`) or `date` (`YYYY-MM-DD`). A name keeps one
|
|
82
|
+
type across the whole file, in every list that declares it.
|
|
83
|
+
- `required` is `true` or `false`, `false` when absent: `gemba create` refuses a task
|
|
84
|
+
without a value for a required field.
|
|
85
|
+
- `description` is optional and not empty: agents map the user's words to the field
|
|
86
|
+
by its name and description, and ask for a required value with it.
|
|
87
|
+
- A declaration takes no other key.
|
|
88
|
+
|
|
89
|
+
The fields of a workstream are the shared ones and its own, joined by name: a field the
|
|
90
|
+
workstream declares with the name of a shared one replaces that declaration entirely.
|
|
91
|
+
|
|
92
|
+
### Process blocks
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
create:
|
|
96
|
+
context: Every task is billed to one client.
|
|
97
|
+
rules:
|
|
98
|
+
- ask who requested the work if not stated
|
|
99
|
+
worktree:
|
|
100
|
+
add:
|
|
101
|
+
rules:
|
|
102
|
+
- start from the default branch of origin
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- A block holds `context`, a string the agent reads as background, and `rules`, a list
|
|
106
|
+
of non-empty strings the agent follows. Both are optional.
|
|
107
|
+
- `create`, `list`, `record`, `report`, `mark`, `archive` and `set` are one verb each:
|
|
108
|
+
the block sits directly under the process name.
|
|
109
|
+
- `harness` and `worktree` are groups: the block sits under each verb, `harness.launch`,
|
|
110
|
+
`harness.note`, `harness.resolve`, `harness.remove`, `worktree.add`, `worktree.list`
|
|
111
|
+
and `worktree.remove`. A group takes no other key, except `harness.guide`.
|
|
112
|
+
- `harness.guide` is a non-empty string written into the guide of every harness
|
|
113
|
+
launched afterwards: the top-level text under `## Your organization` and the
|
|
114
|
+
workstream's under `## Your workstream`. A harness already launched keeps its guide.
|
|
115
|
+
- The block that applies to a workstream joins the top level and the workstream: the
|
|
116
|
+
top-level context then the workstream's, every top-level rule then every rule of the workstream, the rule of
|
|
117
|
+
the workstream winning a contradiction. `gemba config show` prints it joined, under
|
|
118
|
+
`processes` of each workstream.
|
|
119
|
+
|
|
120
|
+
## Process
|
|
121
|
+
|
|
122
|
+
1. **Locate the config.** Walk up from the current folder to the first folder that holds
|
|
123
|
+
`gemba.yaml`: it is the tasks repo root. If there is none, stop and tell the user
|
|
124
|
+
that a tasks repo is started with `gemba init` and configured the first time through
|
|
125
|
+
the `gemba-init` skill.
|
|
126
|
+
2. **Read the current state** with `gemba config show`, and read `gemba.yaml` itself,
|
|
127
|
+
since the edit is made there. When the command refuses, the file is already invalid:
|
|
128
|
+
tell the user and go to step 5 with the problem it names.
|
|
129
|
+
3. **Ask for what the edit needs and the user did not say**, one question at a time,
|
|
130
|
+
proposing a value from what they said: for a workstream, its identifier, prefix and
|
|
131
|
+
description; for a field, its name, type, whether it is required, its description,
|
|
132
|
+
and whether every workstream shares it or one workstream holds it; for a rule or a
|
|
133
|
+
context, the process or verb and whether it is shared or belongs to one workstream.
|
|
134
|
+
Check each value against the reference and the current state: an identifier or a
|
|
135
|
+
prefix already in use, or a field name declared with another type, is refused. Do
|
|
136
|
+
not ask for what the user did not raise and has a default, such as `branch_prefix`.
|
|
137
|
+
4. **Edit `gemba.yaml`** with your own tools, changing only what the edit needs: keep
|
|
138
|
+
every other line, comment, key and their order as they were, and write new keys in
|
|
139
|
+
the style of the file. Never rewrite the file from the output of `gemba config show`:
|
|
140
|
+
it holds defaults and joined blocks that the file does not.
|
|
141
|
+
5. **Check the file:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
gemba config check
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
It exits 0 with a summary when the config is valid; otherwise it exits 1 naming the
|
|
148
|
+
file and the first problem. Fix that problem and run it again until it exits 0: it
|
|
149
|
+
reports one problem at a time. Never leave an invalid config behind, since every
|
|
150
|
+
command refuses to run while it is.
|
|
151
|
+
6. **Refresh the skills when `agent_providers` changed**, from the tasks repo root:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
gemba skills update
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
It writes the skills of a provider added. A provider removed keeps its skills
|
|
158
|
+
folder: tell the user that `.claude/skills/` or `.agents/skills/` is left for them to
|
|
159
|
+
delete. A harness keeps the providers it was launched with.
|
|
160
|
+
7. **Report** what changed in the file, the summary `gemba config check` printed and
|
|
161
|
+
what follows from the edit: the skills written, a folder left to delete, tasks whose
|
|
162
|
+
values no longer match a field. Do not commit: the user reviews and commits the
|
|
163
|
+
tasks repo.
|
|
164
|
+
|
|
165
|
+
## Rules
|
|
166
|
+
|
|
167
|
+
- The CLI never writes `gemba.yaml`. Edit it by hand, and run `gemba config check`
|
|
168
|
+
after every edit.
|
|
169
|
+
- Never move, rename or edit a task file because the config changed. A workstream
|
|
170
|
+
renamed or removed leaves its folder under `tasks/` as it is, and `gemba list`
|
|
171
|
+
reports that folder as a problem until the user moves it; a prefix changed leaves
|
|
172
|
+
every ref already allocated as it is; a field changed leaves every value already
|
|
173
|
+
written as it is, and a value no longer of its field's type is reported until
|
|
174
|
+
`gemba set` writes it again. Tell the user so.
|
|
175
|
+
- No organization's names belong in a skill or in the CLI: every workstream, field and
|
|
176
|
+
rule of the tasks repo lives in its `gemba.yaml`.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-create
|
|
3
|
+
description: Register a new task in this tasks repo. Use whenever the user asks to register, create, track or add a task, TODO or work item, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Create a task
|
|
7
|
+
|
|
8
|
+
Register one unit of work as a task file. The `gemba create` command validates the
|
|
9
|
+
request, allocates the ref and writes the file. Your part is to choose the workstream,
|
|
10
|
+
gather what the config requires, run the command and complete the body.
|
|
11
|
+
|
|
12
|
+
Every organization-specific value (workstreams, prefixes, metadata fields, rules) lives
|
|
13
|
+
in `gemba.yaml`. Run `gemba config show` on every run and rely on nothing else you know
|
|
14
|
+
or remember about workstreams or fields: it prints the config resolved, with the fields
|
|
15
|
+
and the blocks shared by every workstream already joined to those of each one.
|
|
16
|
+
|
|
17
|
+
## Prerequisite
|
|
18
|
+
|
|
19
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
20
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
21
|
+
found, stop and tell the user to install it with that command. Do not run the package's
|
|
22
|
+
Python files directly and do not write the task file by hand.
|
|
23
|
+
|
|
24
|
+
## Process
|
|
25
|
+
|
|
26
|
+
1. **Locate the config.** Walk up from the current folder to the nearest `gemba.yaml`.
|
|
27
|
+
That folder is the tasks repo root. If there is none, stop and tell the user that no
|
|
28
|
+
gemba config was found.
|
|
29
|
+
2. **Choose the workstream.** Run `gemba config show` from anywhere inside the tasks
|
|
30
|
+
repo: it prints the config resolved as one JSON document, or the problem when the
|
|
31
|
+
config is invalid, which you relay before stopping. Compare the request with the
|
|
32
|
+
`description` of every entry of `workstreams` in the document:
|
|
33
|
+
- one description clearly covers the work: use that workstream without asking;
|
|
34
|
+
- no description covers it: use `default_workstream`;
|
|
35
|
+
- two or more cover it equally well: ask the user which one before creating anything.
|
|
36
|
+
3. **Read the fields of the chosen workstream.** The `metadata` of its entry lists every
|
|
37
|
+
field the task may hold, each with its `name`, `type`, `required` and `description`.
|
|
38
|
+
4. **Read the `create` block** of the chosen workstream, `processes.create` of its entry.
|
|
39
|
+
Read its `context` as background and follow every entry of its `rules` in order,
|
|
40
|
+
including any question a rule tells you to ask; when two rules contradict, follow
|
|
41
|
+
the later one.
|
|
42
|
+
5. **Gather required fields.** For every field with `required: true` whose value the user
|
|
43
|
+
has not given, ask for it, phrasing the question with the field's `description` when
|
|
44
|
+
it has one. Ask for all of them in one message. Never ask for optional fields; pass
|
|
45
|
+
an optional field only when the user mentioned its value.
|
|
46
|
+
6. **Write each value by its type.** Every field declares a `type`, and the command
|
|
47
|
+
converts the value by it:
|
|
48
|
+
- `text`: the value exactly as it should read; a field of this type alone holds a
|
|
49
|
+
list, given by repeating the key;
|
|
50
|
+
- `number`: a decimal such as `3`, `2.5` or `-1`;
|
|
51
|
+
- `boolean`: `true` or `false`;
|
|
52
|
+
- `date`: `YYYY-MM-DD`.
|
|
53
|
+
|
|
54
|
+
For a `text` field, look up the values already in use before writing one:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gemba report --by <field> --include-archived
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The `key` of each group is a value in use. When the user means one of them, written
|
|
61
|
+
another way (another case, an abbreviation), pass it with the spelling in use; when
|
|
62
|
+
you cannot tell whether the user means a value in use or a new one, ask.
|
|
63
|
+
7. **Build the slug** from what the user said. It is the task's title: a few lowercase
|
|
64
|
+
ASCII words or numbers joined by single hyphens, matching `^[a-z0-9]+(-[a-z0-9]+)*$`.
|
|
65
|
+
Transliterate accented letters and drop punctuation.
|
|
66
|
+
8. **Run the command** from anywhere inside the tasks repo root:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
gemba create --workstream <id> --slug <slug> \
|
|
70
|
+
[--date YYYY-MM-DD] [--status in-progress|blocked] \
|
|
71
|
+
[--description "<short description>"] [--set <key>=<value> ...]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- Pass `--date` only when the user states a creation date other than today.
|
|
75
|
+
- Pass `--status` only when the user says the work is already in progress or blocked.
|
|
76
|
+
New tasks are `open` by default and `done` is refused.
|
|
77
|
+
- Pass `--set` once per value, written as step 6 says; repeat the key of a `text`
|
|
78
|
+
field to give a list. Values are never read as YAML: text is kept exactly as
|
|
79
|
+
written. Quote the argument for the shell when it contains spaces.
|
|
80
|
+
- Never choose a ref: the command allocates it. An external identifier such as a
|
|
81
|
+
ticket key or a link goes into a declared metadata field or into the body, never
|
|
82
|
+
into the slug.
|
|
83
|
+
|
|
84
|
+
If the command refuses, its message lists every problem at once, including every
|
|
85
|
+
missing and every undeclared key and every value that is not of its field's type. Fix the call, asking the user when a value is
|
|
86
|
+
missing, and run it again. Never work around a refusal by writing or editing the
|
|
87
|
+
file yourself.
|
|
88
|
+
9. **Complete the body.** The command prints the created path, relative to the tasks
|
|
89
|
+
repo root, and the ref. If you did not pass `--description`, write a short description
|
|
90
|
+
above `## Updates` now. Add links to any external references the user gave below
|
|
91
|
+
the description. Edit only the body and leave `## Updates` empty.
|
|
92
|
+
10. **Report** the path, the ref and a one-line summary to the user. Do not commit.
|
|
93
|
+
|
|
94
|
+
## Rules
|
|
95
|
+
|
|
96
|
+
- Commands own the frontmatter, including `metadata`; you own the body. Never edit the
|
|
97
|
+
frontmatter by hand, not even to fix a value; tell the user what is wrong instead.
|
|
98
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
99
|
+
a workstream, field or rule is added, changed or removed.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-harness
|
|
3
|
+
description: Launch, start or open the harness of a task, file notes inside one, and remove one. Use whenever the user asks to launch, start, open or work on a task in its own harness, to remove, delete, throw away or clean up the harness of a task, or, inside a harness, to note, file or log a finding, a blocker, a decision, a summary or an action to take outside it, or to act on a note the user approved, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Work in a harness
|
|
7
|
+
|
|
8
|
+
A harness is the folder of one run of one task: its own git repository and the root the
|
|
9
|
+
IDE opens. The `gemba harness` commands create it, file its notes, record what was
|
|
10
|
+
done on an approved note and remove it. Your part is to write the notes, choose their
|
|
11
|
+
type, run the commands with the right arguments and relay what they print.
|
|
12
|
+
|
|
13
|
+
Every organization-specific value (workstreams and their rules) lives in `gemba.yaml`,
|
|
14
|
+
at the tasks repo root. Run `gemba config show` on every run and rely on nothing else
|
|
15
|
+
you know or remember about workstreams. It prints the config resolved, from the tasks
|
|
16
|
+
repo or from inside a harness: the entry of each workstream holds, under `processes`,
|
|
17
|
+
the block of every verb that applies to it, such as `processes.harness.note`, with the
|
|
18
|
+
block shared by every workstream already joined to the workstream's. Wherever this
|
|
19
|
+
skill says to read a block, read its `context` as background and follow every entry of
|
|
20
|
+
its `rules` in order; when two rules contradict, follow the later one.
|
|
21
|
+
|
|
22
|
+
## Prerequisite
|
|
23
|
+
|
|
24
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
25
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
26
|
+
found, stop and tell the user to install it with that command. Never create, rename or
|
|
27
|
+
commit a file of the harness by hand, and never write a frontmatter.
|
|
28
|
+
|
|
29
|
+
## Launch
|
|
30
|
+
|
|
31
|
+
From anywhere inside the tasks repo:
|
|
32
|
+
|
|
33
|
+
1. **Identify the task by its ref**, `<PREFIX>-<N>`. When the request names the task by
|
|
34
|
+
its title or description instead, find it with the `gemba-list` skill; when two or
|
|
35
|
+
more tasks fit, ask the user which one before launching anything.
|
|
36
|
+
2. **Read the `harness.launch` block:** run `gemba config show` and read
|
|
37
|
+
`processes.harness.launch` in the entry of `workstreams` whose `prefix` is the prefix
|
|
38
|
+
of the ref. Read `context` as background and follow every entry of `rules`.
|
|
39
|
+
3. **Run the command:**
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
gemba harness launch <ref>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pass `--no-open` only when the user says not to open the IDE. If the command
|
|
46
|
+
refuses, relay its message; never work around it.
|
|
47
|
+
4. **Relay the result** and stop: the harness path it printed, the status line (the
|
|
48
|
+
task moved to `in-progress`, or left as it was), and whether the IDE was opened (an
|
|
49
|
+
`opening:` line) or not. When it says the harness is already launched, say so. The
|
|
50
|
+
work itself happens in a session started inside the harness.
|
|
51
|
+
|
|
52
|
+
## Note
|
|
53
|
+
|
|
54
|
+
Inside a harness, every time there is something to record. Paths are relative to the
|
|
55
|
+
harness root, the folder that holds `harness.yaml`.
|
|
56
|
+
|
|
57
|
+
1. **Draft the note** as a plain Markdown file directly under `notes/`, with your own
|
|
58
|
+
tools, named `<slug>.md`: a few lowercase ASCII words or numbers joined by single
|
|
59
|
+
hyphens, such as `notes/login-trace.md`. Write the body only: no frontmatter, no date,
|
|
60
|
+
no timestamp. Keep it to one finding, decision or step; an `external-action` note
|
|
61
|
+
says word for word what is to be done, where and with which values.
|
|
62
|
+
2. **Save the evidence first.** Each asset goes under `assets/`, named
|
|
63
|
+
`<unix-timestamp>-<slug>.<ext>`. Read the timestamp from the system clock with
|
|
64
|
+
`date "+%s %F"`, whose first value is the timestamp; never make one up. Mention each
|
|
65
|
+
asset in the body of the note that explains it.
|
|
66
|
+
3. **Choose the type** by the question the note answers:
|
|
67
|
+
|
|
68
|
+
| Type | The question it answers |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `finding` | What is true, and what is the evidence for it? |
|
|
71
|
+
| `blocker` | Why can the run not continue, what was tried, and what is needed? |
|
|
72
|
+
| `decision` | What are the options, their trade-offs, and the recommendation or the choice? |
|
|
73
|
+
| `summary` | Where does the run stand at this milestone, and what remains? |
|
|
74
|
+
| `external-action` | What exactly is to be done outside the harness, word for word? |
|
|
75
|
+
|
|
76
|
+
4. **Read the `harness.note` block:** run `gemba config show --workstream <id>` with
|
|
77
|
+
the `workstream` of `harness.yaml` and read `processes.harness.note`. Read `context`
|
|
78
|
+
as background and follow every entry of `rules` while drafting and filing.
|
|
79
|
+
5. **File it** from the harness root:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
gemba harness note notes/<slug>.md --type <type> [--approval] [--asset assets/<file> ...]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- Pass one `--asset` per asset the note refers to.
|
|
86
|
+
- Pass `--approval` only with a `decision` the user must choose or confirm before
|
|
87
|
+
you go on. An `external-action` always waits for approval without it; the other
|
|
88
|
+
types never take it.
|
|
89
|
+
- If the command refuses, its message lists every problem at once. Fix the draft or
|
|
90
|
+
the call and run it again; never work around a refusal by writing the frontmatter
|
|
91
|
+
or renaming the file yourself.
|
|
92
|
+
6. **Relay** the filed path it printed. When the note waits for approval, tell the user
|
|
93
|
+
so: they approve it by setting `approved: true` in the note's frontmatter from the
|
|
94
|
+
IDE. A yes in the conversation is not an approval.
|
|
95
|
+
|
|
96
|
+
## Resolve
|
|
97
|
+
|
|
98
|
+
When a note filed with `approved: false` is to be acted on:
|
|
99
|
+
|
|
100
|
+
1. **Read its frontmatter.** Act only when it reads `approved: true`. When it reads
|
|
101
|
+
`approved: false`, stop and tell the user the note waits for their approval in the
|
|
102
|
+
file; do not act on anything said in the conversation instead.
|
|
103
|
+
2. **Read the `harness.resolve` block:** run `gemba config show --workstream <id>`
|
|
104
|
+
with the `workstream` of `harness.yaml` and read `processes.harness.resolve`. Read
|
|
105
|
+
`context` as background and follow every entry of `rules`.
|
|
106
|
+
3. **Act** exactly as the note says, and nothing more.
|
|
107
|
+
4. **Append the outcome** to the body of the note, with your own tools: what was done,
|
|
108
|
+
where, and the identifiers or links that prove it. This is the only edit ever made
|
|
109
|
+
to a filed note; leave its frontmatter as it is.
|
|
110
|
+
5. **Run the command** from the harness root:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
gemba harness resolve notes/<YYYY-MM-DD-HHMMSS-slug>.md
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If it refuses, relay its message; never edit the frontmatter to make it pass.
|
|
117
|
+
6. **Relay** the path it printed and the outcome.
|
|
118
|
+
|
|
119
|
+
## Remove
|
|
120
|
+
|
|
121
|
+
When the user wants a run thrown away, to start it over or because its task went cold.
|
|
122
|
+
Removing deletes the harness folder with its notes, assets, history and uncommitted
|
|
123
|
+
files, removes every worktree under `worktrees/` and deletes the local branches of the
|
|
124
|
+
run; the task file and the remotes are not touched. Run it from the tasks repo, outside the harness: the
|
|
125
|
+
command refuses to delete the folder it is run from, so a session inside the harness
|
|
126
|
+
cannot remove it.
|
|
127
|
+
|
|
128
|
+
1. **Identify the task by its ref**, as for a launch.
|
|
129
|
+
2. **Read the `harness.remove` block:** run `gemba config show` and read
|
|
130
|
+
`processes.harness.remove` in the entry of `workstreams` whose `prefix` is the prefix
|
|
131
|
+
of the ref. Read `context` as background and follow every entry of `rules` before
|
|
132
|
+
showing the manifest.
|
|
133
|
+
3. **Show the manifest** by running the command without `--yes`:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
gemba harness remove <ref>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
It prints the harness path, the task, the launch date and the number of notes,
|
|
140
|
+
assets, commits and worktrees (`worktrees:`), the number of uncommitted files of the
|
|
141
|
+
harness (`uncommitted:`) followed by one `- <path>` line per file, then
|
|
142
|
+
`not removed: pass --yes to delete the harness`, and deletes nothing.
|
|
143
|
+
4. **Ask the user.** Show them the manifest, ask whether to delete the harness, its
|
|
144
|
+
worktrees and the local branches of the run, and remind them to close any IDE window
|
|
145
|
+
open on that folder first. When `uncommitted:` is not 0, name each path listed under
|
|
146
|
+
it, say that it is deleted with the harness, and say what would keep it should the
|
|
147
|
+
user want to, from a session inside the harness: a draft under `notes/` is filed with
|
|
148
|
+
`gemba harness note`, an `update.md` is recorded with `gemba record`; anything else
|
|
149
|
+
they may copy elsewhere. Never file, commit or delete any of them yourself. A yes in the conversation is enough here: the harness,
|
|
150
|
+
its worktrees and their branches are local, so no `external-action` note is needed.
|
|
151
|
+
5. **Delete only after a yes**, by running the same command with `--yes`:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
gemba harness remove <ref> --yes
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
When the user says no, stop.
|
|
158
|
+
6. **Relay the result**: `removed` when the harness is gone. A later
|
|
159
|
+
`gemba harness launch <ref>` creates a fresh harness for the same task.
|
|
160
|
+
|
|
161
|
+
When the command prints `harness not removed:`, in either step, relay every line and
|
|
162
|
+
tell the user how each one is saved, from a session inside the harness:
|
|
163
|
+
|
|
164
|
+
- `worktrees/<repo> has N uncommitted paths`: a commit inside that worktree saves them,
|
|
165
|
+
and the commit then needs a push like any other.
|
|
166
|
+
- `worktrees/<repo> has N commits not on any remote branch`: a push from inside the
|
|
167
|
+
worktree saves them, and it needs an `external-action` note whose frontmatter reads
|
|
168
|
+
`approved: true` and that names the branch of the remote.
|
|
169
|
+
- `branch <branch> of <repo> has N commits not on any remote branch and no worktree`: a
|
|
170
|
+
branch of the run left by a harness deleted by hand. Only the user can push it, from
|
|
171
|
+
that repository; you never run git there.
|
|
172
|
+
- `worktrees/<name> is not a worktree`: a folder gemba did not create there; the user
|
|
173
|
+
moves it elsewhere if it is needed.
|
|
174
|
+
|
|
175
|
+
Saving is the user's decision, carried out in a session inside the harness: from the
|
|
176
|
+
tasks repo, never file, commit, push or delete anything yourself to make the removal
|
|
177
|
+
pass, and never delete the folder by other means.
|
|
178
|
+
|
|
179
|
+
**Never force first.** `--force` discards the uncommitted paths and unpushed commits of
|
|
180
|
+
the worktrees, the unpushed commits of the branches of the run and the folders that are
|
|
181
|
+
not worktrees. Never pass it on the first run, even when the user asks to force the
|
|
182
|
+
removal: run the command without it, relay every line it reports, and pass
|
|
183
|
+
`--yes --force` only after the user confirms, in the conversation, that everything in
|
|
184
|
+
that list is to be discarded. `--force` never covers a working directory inside the
|
|
185
|
+
harness nor a harness repository whose state cannot be read: those still refuse.
|
|
186
|
+
|
|
187
|
+
## Rules
|
|
188
|
+
|
|
189
|
+
- Commands own the frontmatter of the task and of every note, and `harness.yaml`; you
|
|
190
|
+
own the bodies of the notes. `task.md` is read-only.
|
|
191
|
+
- Nothing outside the harness happens without an `external-action` note whose
|
|
192
|
+
frontmatter reads `approved: true`.
|
|
193
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
194
|
+
a workstream or a rule is added, changed or removed.
|