1# nasin pali (the way of work)
2
3[](https://api.reuse.software/info/git.secluded.site/nasin-pali)
4[](https://goreportcard.com/report/git.secluded.site/nasin-pali)
5
6**This README is aspirational!** None of the code exists yet, I'm just getting
7my ideas down. I previously wrote a
8[planning-mcp-server](https://git.secluded.site/planning-mcp-server) that I'll
9keep some ideas from, and the overall workflow is about the same. I'm trying a
10CLI over MCP because MCP seems quite protocol-heavy for what _could_ just be a
11few simple CLI invocations. Maybe connecting arbitrary data sources warrants a
12whole protocol like MCP, but I don't think something as basic as this does. Just
13some thoughtful design and prompting.
14
15---
16
17## Overview
18
19_nasin pali_, installed as `np`, is a CLI tool that encourages LLMs in agentic
20coding tools (specifically coding, I don't think we want to support generic
21workflows) to do a bit more planning before going off and making a bunch of
22changes. It is _both_ meant for humans and LLMs; there are subcommands that
23produce output for the model and subcommands for the human to inspect the
24model's progress. There's a section on [the name](#the-name) if you're curious
25about it.
26
27The todo systems built into agentic coding tools are often just that: todo and
28nothing else. I think (backed by no evidence) that they do better when they can
29also set a goal. If I understand the coding tools correctly, they also have the
30LLM reproduce the entire task list with each `todo_write` invocation, which just
31seems wasteful and careless to me. What if it decides it doesn't want to do a
32task because it's "too hard" and it just omits that task next time it writes the
33list? _nasin pali_ helps force the model into a different overall flow.
34
35## Expected workflow
36
37_This is what I like, I'd be happy to hear of other workflows that lead to
38better/different success and to consider whether nasin-pali can support them_
39
40The operator is expected to load the prompt up with relevant text. Type the
41issue in the prompt, paste the bug report, tell it how to fetch the issue from
42your issue tracker, whatever you like. If the issue content is too sparse, make
43sure to add more context. The more context you give and the higher its quality
44and relevancy, the better results you'll have. Include paths to as many files
45you know will be relevant as possible. Mention particular symbols, paste
46snippets of code, etc. Once your prompt looks good, send it off.
47
48In the `np` section of the model's rules, we'll have instructions to
49_immediately_ run start a session if the operator says to `use np` or something
50similar. Each command further in the flow reveals the next step as instructions.
51`np s` tells the model to set an overarching goal with `np g s -t title -d
52description` that captures the operator's request, combining the information
53from the ticket and any extra operator-provided context. If there's a ticket ID,
54that goes in the goal description. The output of `np g s` says to look at the
55provided references, thoroughly consider how to go about resolving the goal, and
56gather additional context from other files if necessary. Once it has a good idea
57how to resolve the goal, it should add some tasks with `np t a -t title -d
58description -t title2 -d description2`. The descriptions are good places to
59reference files and symbols. The output of `np t a` tells it to update tasks as
60it works on them with something like `np t u -i task-id -s status`.
61
62Commands that modify the model's goal or list output the full changed plan
63(formatted [like so](#the-format-the-model-sees)) so it doesn't have to run
64another command to check, obviating patterns like `git status` after every `git
65commit`. It can use `np p` to check the plan (goal, desc, remaining tasks,
66descs) and use `np t -s status` to filter to `pending`, `in progress`,
67`completed`, `all`, etc. tasks, but usually doesn't need to because we
68immediately show it after every modification.
69
70Resume an interrupted session in a _new_ context window by telling the model to
71run `np r`. This outputs the full plan, provides relevant usage instructions,
72and tells the model to "check above" for a bug/issue/ticket ID in the goal
73description. If present, read that. Then read the files/symbols referenced in
74the pending tasks to get a good idea of what work is left.
75
76Once finished, the operator or model (I'm not sure which yet, see next section)
77archives the session with `np a`.
78
79## Details
80
81### Session scoping
82
83Each session is working-directory-scoped so neither the model nor the human
84_have_ to provide a session ID or something for each invocation like `np s -s
85session-id -t title -d description`. This is why there are `np s` and `np a`
86commands for `s`tarting and `a`rchiving a session. There can only be one session
87in progress per directory, so worktrees allow for parallel sessions.
88
89I'm unsure who should archive the session. I like the idea of requiring the
90operator to, meaning we can leave that bit out of the model's rules, but maybe
91the coding tool has no way for the operator to execute shell commands. In that
92case, they'd have to type the whole thing to the model or quit/open a new shell
93to archive themselves before the model can start a new session. Maybe telling
94the model about the archival command, but to never run it without explicit
95instruction from the operator, would be sufficient.
96
97### Event tracking
98
99Every LLM-oriented sub-command is tracked as an event in a global SQLite
100database in `$XDG_CONFIG_HOME/nasin-pali/`. Sub-commands that do anything to
101modify either created tasks or set goals require a reason ("operator said so" is
102insufficiently detailed, but otherwise acceptable).
103
104### Event rendering
105
106The interactive, human-focused sub-commands are for watching these events and
107the resulting list as they change in real-time-ish. The goal and description and
108tasks and their descriptions are rendered at the top of the UI and updated based
109on database events using some Charm libraries. Change events are underneath the
110rendered state, sorted most recent (top) to least recent (bottom).
111
112### The format the model sees
113
114It uses individual unicode symbols to represent task statuses. This costs one
115token per status where more verbose checkboxes `- [x]` or words `completed`
116might use more. The failed icon (`☒`) and cancelled icon (`⊗`) are only shown in
117the legend if there are actually failed or cancelled tasks in the list.
118
119```
120Create a comprehensive MCP server for task planning and management
121
122Legend: ☐ pending ⟳ in progress ☑ completed
123☑ Set up project structure [a1b2c3d4]
124 Create Go module, directories, and basic files
125⟳ Implement core planning logic [e5f6g7h8]
126 Create Goal and Task data structures with deterministic IDs
127☐ Build MCP server integration [i9j0k1l2]
128```
129
130## The name
131
132Is from [toki pona](https://tokipona.org/), _a simple language_.
133[_nasin_](https://nimi.li/nasin) occupies the semantic space of "method,
134doctrine, tradition; path, road, way" while [_pali_](https://nimi.li/pali)
135covers "work, activity; create, build, design; put effort toward, take action
136on". Together and in this context, _nasin pali_ could be translated as "the way
137of work", "the doctrine of design", etc.
138
139## Random thoughts
140
141- When providing multiple lines for the body, use
142
143 ```bash
144 np g s -t "Sentence case title" -d "$(cat <<'EOF'
145 Multi-line
146 - Body
147 - Here
148
149 EOF
150 )"
151 ```