README.md

  1# nasin pali (the way of work)
  2
  3[![REUSE status](https://api.reuse.software/badge/git.secluded.site/nasin-pali)](https://api.reuse.software/info/git.secluded.site/nasin-pali)
  4[![Go Report Card](https://goreportcard.com/badge/git.secluded.site/nasin-pali)](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 `np s`, which outputs some LLM-oriented instructions for use.
 50It first tells the model to set an overarching goal with `np g s -t title -d
 51description` that captures the operator's request, combining the information
 52from the ticket and any extra operator-provided context. Then it should go off
 53and look at the provided references and thoroughly consider how to go about
 54resolving the goal. After gathering that context, it adds tasks with `np t a -t
 55title -d description -t title2 -d description2` and gets started on them.
 56
 57As it works through the tasks, it's expected to update statuses by ID with
 58something like `np t u -i id -s status`. Commands that modify the model's plan
 59output the revision so it can immediately see the result of its invocation
 60without running another command (obviating patterns like running `git status`
 61after every `git commit`). Format the list something like this, using individual
 62unicode symbols to represent task statuses using one token per status instead of
 63more verbose checkboxes `- [x]` or words `completed` that might use more tokens.
 64The failed icon (`☒`) and cancelled icon (`⊗`) are only shown in the legend if
 65there are actually failed or cancelled tasks in the list.
 66
 67```
 68Create a comprehensive MCP server for task planning and management
 69
 70Legend: ☐ pending  ⟳ in progress  ☑ completed
 71☑ Set up project structure [a1b2c3d4]
 72  Create Go module, directories, and basic files
 73⟳ Implement core planning logic [e5f6g7h8]
 74  Create Goal and Task data structures with deterministic IDs
 75☐ Build MCP server integration [i9j0k1l2]
 76```
 77
 78I'm unsure how to handle session archival (mentioned in [random
 79thoughts](#random-thoughts)). We could tell the model how to archive sessions in
 80the rules, but I don't know that the model even needs to know about sessions;
 81maybe archival should require human interaction. If the model can't archive
 82sessions, and the agentic coding tool doesn't have a way for the operator to
 83execute shell commands, they'd have to quit or open a new shell to run that
 84command before the model can create a new session. Maybe telling it about the
 85archival command, but to never run it without operator interaction, would be
 86sufficient.
 87
 88Every LLM-oriented sub-command is tracked as an event in a global SQLite
 89database in `$XDG_CONFIG_HOME/nasin-pona/`. Sub-commands that do anything to
 90modify either created tasks or set goals require a reason ("operator said so" is
 91insufficiently detailed, but otherwise acceptable).
 92
 93The interactive, human-focused sub-commands are for watching these events and
 94the resulting list as they change in realtime, and for exporting a session with
 95all of its events as Markdown. The goal and description and tasks and their
 96descriptions are rendered at the top of the UI and updated based on database
 97events using some Charm libraries. Change events are underneath the rendered
 98state, sorted most recent (top) to least recent (bottom).
 99
100Each session is working-directory-scoped so the model doesn't have to provide a
101session ID or something for each invocation. This is why there are `np s` and
102`np a` commands for `s`tarting and `a`rchiving a session. Worktrees allow for
103parallel sessions.
104
105## The name
106
107Is [toki pona](https://tokipona.org/). [_nasin_](https://nimi.li/nasin) occupies
108the semantic space of "method, doctrine, tradition; path, road, way" while
109[_pali_](https://nimi.li/pali) covers "work, activity; create, build, design;
110put effort toward, take action on". Together and in this context, _nasin pali_
111could be translated as "the way of work", "the doctrine of design", etc.
112
113## Random thoughts
114
115- When providing multiple lines for the body, use
116
117  ```bash
118  np goal set "Sentence case title" "$(cat <<'EOF'
119  Multi-line
120  - Body
121  - Here
122
123  EOF
124  )"
125  ```
126
127- Start a new session with `np s`. It adds details to the global sqlite database
128  and produces output to guide the LLM through its next steps. Instead of
129  telling the model up-front about everything it can do with _nasin pali_ though
130  AGENTS.md or tool definitions or something, we only reveal the sub-commands
131  and flags it might actually need once it needs them. It shouldn't ever use the
132  interactive commands, so we never tell them model about them.
133  - There can be one active session per working directory and the previous
134    session must be archived before starting a new one. This is so the model
135    doesn't have to provide a session ID or something for each invocation.
136- `np s` tells the model about the goal and task sub-commands and their flags
137  and to begin the session by turning the user's request, bug report, issue
138  contents, spec, etc. into a concise overarching goal with a thorough
139  description.
140- `np g s` accepts title and description arguments and tells the model to, if
141  necessary, look around at additional relevant files before adding some tasks
142  with `np t a`. <mark>How to provide/require/validate for pairs of -t and -d
143  flags?</mark>
144- Have the model update task statuses by ID and render the goal, the updated
145  task, and the _remaining_ tasks in the same format as planning-mcp-server. By
146  default, `planning-mcp-server` returned all tasks, but I think it would be
147  better to just return the modified one, so the model can see its previous
148  command worked, and the still-open ones. Include a flag or something so it can
149  look at all tasks including the completed ones.