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