@nanocollective/roster 0.1.0-alpha.5 → 0.1.0-alpha.50

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.
Files changed (102) hide show
  1. package/README.md +70 -84
  2. package/dist/cli.js +4833 -2752
  3. package/docs/README.md +9 -6
  4. package/docs/agents.md +24 -20
  5. package/docs/architecture.md +13 -5
  6. package/docs/charters/analyst.md +65 -0
  7. package/docs/charters/cmo.md +69 -0
  8. package/docs/charters/community.md +63 -0
  9. package/docs/charters/cto.md +71 -0
  10. package/docs/charters/designer.md +65 -0
  11. package/docs/charters/devops.md +65 -0
  12. package/docs/charters/pm.md +70 -0
  13. package/docs/charters/qa.md +65 -0
  14. package/docs/charters/support.md +60 -0
  15. package/docs/charters/writer.md +63 -0
  16. package/docs/commands.md +93 -7
  17. package/docs/concepts.md +61 -14
  18. package/docs/cost.md +36 -1
  19. package/docs/developing.md +16 -21
  20. package/docs/doctor-codes.md +10 -2
  21. package/docs/export.md +2 -0
  22. package/docs/extending.md +2 -2
  23. package/docs/getting-started.md +128 -78
  24. package/docs/images/brain.jpg +0 -0
  25. package/docs/images/org.jpg +0 -0
  26. package/docs/images/prompt.jpg +0 -0
  27. package/docs/images/setup-org.jpg +0 -0
  28. package/docs/images/setup-plan.jpg +0 -0
  29. package/docs/images/staff.jpg +0 -0
  30. package/docs/manual-steps.md +94 -123
  31. package/docs/memory.md +21 -3
  32. package/docs/org-yaml.md +40 -2
  33. package/docs/portal.md +165 -48
  34. package/docs/prompts.md +31 -4
  35. package/docs/security.md +37 -5
  36. package/docs/session-workflow.md +63 -17
  37. package/docs/staff-yaml.md +30 -3
  38. package/docs/troubleshooting.md +8 -8
  39. package/docs/upgrading.md +9 -3
  40. package/docs/writing-a-charter.md +28 -0
  41. package/package.json +18 -20
  42. package/templates/brain/.github/workflows/%%STAFF%%-daily.yaml +26 -1
  43. package/templates/brain/.github/workflows/%%STAFF%%-mention.yaml +41 -7
  44. package/templates/brain/CHARTER.md +3 -3
  45. package/templates/brain/README.md +1 -0
  46. package/templates/brain/log/decisions.md +3 -0
  47. package/templates/brain/staff.yaml +4 -1
  48. package/templates/brain/strategy/ideas.md +7 -0
  49. package/templates/briefs/priorities.md +46 -0
  50. package/templates/ops/.github/workflows/session.yaml +236 -15
  51. package/templates/ops/agents.mjs +7 -3
  52. package/templates/ops/compose.mjs +31 -3
  53. package/templates/ops/inflight.mjs +157 -0
  54. package/templates/ops/org/operating.md +43 -4
  55. package/templates/ops/org/voice.md +9 -0
  56. package/templates/ops/prompts/_inflight.md +14 -0
  57. package/templates/ops/prompts/_paths.md +2 -1
  58. package/templates/ops/prompts/daily.md +37 -9
  59. package/templates/ops/prompts/mention.md +21 -0
  60. package/templates/ops/run-record.mjs +146 -0
  61. package/templates/portal/css/base.css +167 -73
  62. package/templates/portal/css/brain.css +23 -20
  63. package/templates/portal/css/diff.css +10 -9
  64. package/templates/portal/css/graph.css +12 -7
  65. package/templates/portal/css/health.css +13 -11
  66. package/templates/portal/css/home.css +93 -0
  67. package/templates/portal/css/inbox.css +45 -25
  68. package/templates/portal/css/layout.css +90 -46
  69. package/templates/portal/css/markdown.css +36 -14
  70. package/templates/portal/css/runs.css +13 -0
  71. package/templates/portal/css/setup.css +116 -34
  72. package/templates/portal/index.html +21 -9
  73. package/templates/portal/js/api.js +44 -4
  74. package/templates/portal/js/app.js +94 -9
  75. package/templates/portal/js/dialog.js +83 -0
  76. package/templates/portal/js/homesort.js +174 -0
  77. package/templates/portal/js/icons.js +37 -0
  78. package/templates/portal/js/inflight.js +18 -0
  79. package/templates/portal/js/md.js +5 -2
  80. package/templates/portal/js/mdedit.js +84 -0
  81. package/templates/portal/js/readiness.js +70 -0
  82. package/templates/portal/js/refresh.js +10 -2
  83. package/templates/portal/js/state.js +11 -5
  84. package/templates/portal/js/views/app.js +24 -7
  85. package/templates/portal/js/views/brain.js +1 -1
  86. package/templates/portal/js/views/checklist.js +10 -4
  87. package/templates/portal/js/views/credential.js +84 -0
  88. package/templates/portal/js/views/graph.js +1 -1
  89. package/templates/portal/js/views/health.js +17 -4
  90. package/templates/portal/js/views/hire.js +593 -0
  91. package/templates/portal/js/views/home.js +546 -0
  92. package/templates/portal/js/views/inbox.js +226 -70
  93. package/templates/portal/js/views/org.js +46 -106
  94. package/templates/portal/js/views/orgedit.js +234 -0
  95. package/templates/portal/js/views/paste.js +87 -21
  96. package/templates/portal/js/views/prompt.js +11 -4
  97. package/templates/portal/js/views/repos.js +20 -15
  98. package/templates/portal/js/views/runonce.js +94 -0
  99. package/templates/portal/js/views/runs.js +170 -0
  100. package/templates/portal/js/views/setup.js +261 -75
  101. package/templates/portal/js/views/staff.js +170 -243
  102. package/templates/portal/js/views/todo.js +62 -0
@@ -22,8 +22,10 @@ a coding agent, split into what an agent can fix and what only a person can. `ro
22
22
 
23
23
  **Is:** the ops repo's Actions access is not set to organisation-wide.
24
24
 
25
- Settings -> Actions -> General on `roster-ops`. The setup screen deep-links that exact page,
26
- which is the fastest way to fix it; Health and `roster doctor` both check it explicitly.
25
+ `roster init --apply` sets it, and so does *Set it for me* on the setup screen. If GitHub
26
+ refused (it needs admin on the ops repo), set it by hand: Settings -> Actions -> General ->
27
+ Access on `roster-ops`, "accessible from repositories in the organisation". Health and `roster
28
+ doctor` both check it explicitly.
27
29
 
28
30
  ---
29
31
 
@@ -90,11 +92,9 @@ constrains it is not a thing anybody wants.
90
92
  **Is:** you edited a framework-owned file. `compose.mjs`, `agents.mjs`, `runner-plan.mjs` and
91
93
  `session.yaml` are generated. The next `roster upgrade` reconciles them against the template.
92
94
 
93
- This happened here: a fix went into `roster-ops/.github/workflows/session.yaml` instead of
94
- `templates/ops/...`, and nothing noticed because the framework had not touched that file *yet*.
95
-
96
- `roster upgrade` now reports an edit to a framework-owned file whether or not anything has
97
- collided, and `roster upgrade --check` fails on it. Move the change upstream.
95
+ Nothing notices until the framework next touches that file. `roster upgrade` reports an edit
96
+ to a framework-owned file whether or not anything has collided, and `roster upgrade --check`
97
+ fails on it. Move the change upstream.
98
98
 
99
99
  ---
100
100
 
@@ -181,7 +181,7 @@ landed on GitHub thirty seconds ago and the checkout is behind, that is what you
181
181
 
182
182
  ## `roster upgrade` says a file has no base
183
183
 
184
- A tenant created before the merge base was recorded has nothing to merge against. Reconstruct
184
+ A tenant with no recorded merge base has nothing to merge against. Reconstruct
185
185
  one from the framework's history:
186
186
 
187
187
  ```bash
package/docs/upgrading.md CHANGED
@@ -10,9 +10,9 @@ The framework writes templates out. A tenant runs its own copies. So the two dri
10
10
  `roster upgrade` is what reconciles them without eating your edits.
11
11
 
12
12
  ```bash
13
- roster upgrade # what would change
14
- roster upgrade --apply # do it
15
- roster upgrade --check # exit non-zero if anything is pending (for CI)
13
+ npx @nanocollective/roster@latest upgrade # what would change
14
+ npx @nanocollective/roster@latest upgrade --apply # do it
15
+ npx @nanocollective/roster@latest upgrade --check # exit non-zero if anything is pending (for CI)
16
16
  ```
17
17
 
18
18
  ## How it decides
@@ -53,6 +53,12 @@ The diff is printed either way, so nothing goes quietly.
53
53
  If you want a caller to differ, change the thing it is generated from. Timeouts, schedule,
54
54
  model and identities all live in `staff.yaml`.
55
55
 
56
+ **A caller the framework no longer generates is removed.** It would still dispatch into
57
+ `session.yaml` with a kind that no longer composes, and fail at run time. The plan lists it.
58
+ The one that has gone so far is `<handle>-pr-mention.yaml`; if your tenant is old enough to
59
+ have one, a forwarding workflow in the product repo went with it, and that one is yours to
60
+ delete, because `roster upgrade` never writes into product repos.
61
+
56
62
  ## Conflicts
57
63
 
58
64
  A conflict is never written into a live file. Agents read `org/voice.md` at every boot, and
@@ -28,6 +28,13 @@ layer. That is the part that matters most, because without them the model writes
28
28
  of whoever it was shown. The brief then interviews you, drafts from your answers, and tells you
29
29
  what it cut and why.
30
30
 
31
+ **So is a worked example, when one fits.** A staff member whose handle or role reads as one of
32
+ the ten roles below gets the matching [example](#worked-examples) inside the brief, labelled as a
33
+ model for the shape and not content to copy. The copy-a-prompt panel has a picker to choose
34
+ another or none; in a terminal it is `--example <handle>` or `--example none`. It is still a brief you
35
+ answer: the interview comes first, and nothing in the charter should come from the example
36
+ rather than from you.
37
+
31
38
  From a terminal, the same brief:
32
39
 
33
40
  ```bash
@@ -63,6 +70,27 @@ touches. Be specific. A vague boundary is one that gets crossed at 07:00 with no
63
70
  **Where the rest of it lives.** Point at `memory/INDEX.md`, `log/decisions.md`, the pinned
64
71
  status issue, and the surfaces the manifest declares.
65
72
 
73
+ ## Worked examples
74
+
75
+ Ten, for an invented company called Acme. The handle in brackets is the one `--example` takes.
76
+
77
+ | Example | What they do |
78
+ |---|---|
79
+ | [CTO](charters/cto.md) (`cto`) | Builds the product: fixes, features and tests, as pull requests. |
80
+ | [CMO](charters/cmo.md) (`cmo`) | Posts, SEO, copy and launch plans, as drafts to approve. |
81
+ | [Head of Support](charters/support.md) (`support`) | Answers issues, writes help docs, and turns user reports into bugs. |
82
+ | [Product Manager](charters/pm.md) (`pm`) | Turns ideas and user feedback into clear specs and a ranked backlog. |
83
+ | [Designer](charters/designer.md) (`designer`) | Improves the product's look and usability, with accessibility fixes, as pull requests. |
84
+ | [QA Engineer](charters/qa.md) (`qa`) | Tests the product, finds bugs, and writes clear reproductions and tests. |
85
+ | [DevOps Engineer](charters/devops.md) (`devops`) | Keeps CI, deploys and dependencies healthy, and patches security updates. |
86
+ | [Technical Writer](charters/writer.md) (`writer`) | Writes and keeps up the docs, guides and changelog. |
87
+ | [Data Analyst](charters/analyst.md) (`analyst`) | Reads the numbers and writes a short weekly report on what changed. |
88
+ | [Community Manager](charters/community.md) (`community`) | Answers discussions, welcomes contributors, and drafts release announcements. |
89
+
90
+ They are examples to adapt, not templates to fill in. Read them for what a finished charter covers and how specific it gets, then write your own
91
+ about your business. A charter copied from one of these describes Acme. The brief carries the matching one for
92
+ you; these links are for reading them first.
93
+
66
94
  ## Things worth being concrete about
67
95
 
68
96
  - **Escalation.** Name the label and the mechanism, not the sentiment. "Open an issue labelled
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanocollective/roster",
3
- "version": "0.1.0-alpha.5",
3
+ "version": "0.1.0-alpha.50",
4
4
  "description": "An agent-run org, powered by GitHub. Scaffold AI staff members whose brain is a repo.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,23 +16,6 @@
16
16
  "engines": {
17
17
  "node": ">=20"
18
18
  },
19
- "scripts": {
20
- "build": "tsup src/cli.ts --format esm --target node20 --clean",
21
- "dev": "tsx src/cli.ts",
22
- "test": "tsx --test test/*.test.ts",
23
- "test:all": "pnpm test:format && pnpm test:lint && pnpm test:types && pnpm test:knip && pnpm test",
24
- "test:ava:coverage": "c8 --reporter=text --reporter=json-summary tsx --test test/*.test.ts",
25
- "test:format": "biome check --no-errors-on-unmatched .",
26
- "test:lint": "biome lint .",
27
- "test:lint:fix": "biome check --write .",
28
- "test:types": "tsc --noEmit",
29
- "test:knip": "knip",
30
- "test:audit": "pnpm audit --audit-level=high",
31
- "test:security": "semgrep scan --config auto --error",
32
- "typecheck": "tsc --noEmit",
33
- "format": "biome check --write .",
34
- "prepublishOnly": "pnpm test:all && pnpm build"
35
- },
36
19
  "devDependencies": {
37
20
  "@biomejs/biome": "^2.5.12",
38
21
  "@types/node": "^22.10.2",
@@ -52,9 +35,24 @@
52
35
  "url": "https://github.com/Nano-Collective/roster/issues"
53
36
  },
54
37
  "author": "Nano Collective",
55
- "packageManager": "pnpm@11.0.9",
56
38
  "publishConfig": {
57
39
  "access": "public",
58
40
  "tag": "latest"
41
+ },
42
+ "scripts": {
43
+ "build": "tsup src/cli.ts --format esm --target node20 --clean",
44
+ "dev": "tsx src/cli.ts",
45
+ "test": "tsx --test test/*.test.ts",
46
+ "test:all": "pnpm test:format && pnpm test:lint && pnpm test:types && pnpm test:knip && pnpm test",
47
+ "test:ava:coverage": "c8 --reporter=text --reporter=json-summary tsx --test test/*.test.ts",
48
+ "test:format": "biome check --no-errors-on-unmatched .",
49
+ "test:lint": "biome lint .",
50
+ "test:lint:fix": "biome check --write .",
51
+ "test:types": "tsc --noEmit",
52
+ "test:knip": "knip",
53
+ "test:audit": "pnpm audit --audit-level=high",
54
+ "test:security": "semgrep scan --config auto --error",
55
+ "typecheck": "tsc --noEmit",
56
+ "format": "biome check --write ."
59
57
  }
60
- }
58
+ }
@@ -6,22 +6,47 @@ name: %%STAFF_UPPER%% daily run
6
6
  #
7
7
  # NOTE: %%TOKENS%% are filled by `roster hire`; GitHub's own ${{ }} are left alone.
8
8
 
9
+ # The trigger and the date, as the Actions list shows it. The daily limit counts follow-on runs
10
+ # by this name.
11
+ run-name: "%%STAFF%% ${{ github.event_name == 'schedule' && 'daily' || inputs.trigger || 'manual' }}"
12
+
9
13
  on:
10
14
  schedule:
11
15
  - cron: "%%SCHEDULE%%"
16
+ # By hand, from Run once now, or as a follow-on: a daily run that ended with the next step
17
+ # ready starts one more, up to max_runs_per_day.
12
18
  workflow_dispatch:
19
+ inputs:
20
+ trigger:
21
+ description: "manual | follow-on"
22
+ required: false
23
+ default: manual
24
+ type: string
13
25
 
14
- # A second run while one is in flight would fight it over the tracker and the branch state.
26
+ # A second run while one is in flight would fight it over the tracker and the branch state. A
27
+ # follow-on is started from inside the run before it, so it waits here until that one ends.
15
28
  concurrency:
16
29
  group: %%STAFF%%-session
17
30
  cancel-in-progress: false
18
31
 
19
32
  jobs:
20
33
  session:
34
+ # The ceiling on what session.yaml's job token may do: reading the checkout, and the one
35
+ # comment that says a run failed when the App that would normally say so is what broke.
36
+ # A called workflow cannot raise these, so they have to be granted here.
37
+ #
38
+ # `actions` is for the daily limit, which reads this repo's runs, and for starting a
39
+ # follow-on run, which the job token may do: a workflow_dispatch it sends still starts a run.
40
+ permissions:
41
+ contents: read
42
+ issues: write
43
+ actions: write
21
44
  uses: %%OPS_REPO%%/.github/workflows/session.yaml@main
22
45
  with:
23
46
  staff: %%STAFF%%
24
47
  kind: daily
48
+ trigger: ${{ github.event_name == 'schedule' && 'daily' || inputs.trigger || 'manual' }}
49
+ max_runs_per_day: %%MAX_RUNS%%
25
50
  ops_repo: %%OPS_REPO%%
26
51
  model: %%MODEL%%
27
52
  timeout_minutes: %%TIMEOUT%%
@@ -3,11 +3,18 @@ name: %%STAFF_UPPER%% on a mention
3
3
  # Generated by roster. The body lives in %%OPS_REPO%%/.github/workflows/session.yaml.
4
4
  #
5
5
  # "%%MENTION%% ..." in a comment on this tracker, or in the body of a new issue, wakes a focused
6
- # run in about 30 seconds. It is a task, not a session: no boot ritual, no handoff, and the reply
6
+ # run in about 30 seconds. So does another staff member filing an issue here with their
7
+ # `from-<handle>` label. It is a task, not a session: no boot ritual, no handoff, and the reply
7
8
  # goes in the thread.
8
9
  #
9
10
  # NOTE: %%TOKENS%% are filled by `roster hire`. GitHub's own ${{ }} expressions are left alone.
10
11
 
12
+ # What the run is and what started it, as the Actions list shows it. The portal reads this back
13
+ # to link a live run to the request behind it, and the daily limit counts peer runs by it.
14
+ run-name: >-
15
+ %%STAFF%% ${{ contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.sender.login) && 'mention' || 'peer' }}
16
+ #${{ github.event.issue.number }}
17
+
11
18
  on:
12
19
  # A mention in the body of a brand new issue, which is often the faster route: one box, rather
13
20
  # than a "create, then comment" round trip. `edited` doubles as the way to re-ask without
@@ -44,19 +51,46 @@ jobs:
44
51
  #
45
52
  # One spelling of the mention is enough: GitHub's `contains` is documented as not case
46
53
  # sensitive, so this already matches an uppercase mention at the start of a sentence.
54
+ #
55
+ # The second route is a peer's ask: a new issue opened by an App, never this staff member's
56
+ # own, carrying a `from-<handle>` label. Only `opened`, so the peer editing its own issue
57
+ # later wakes nobody. It names no peer, so a later hire needs no regenerated caller: the only
58
+ # accounts that can open an issue on a private tracker are the people and Apps it is
59
+ # installed for. A peer run may not file on another peer, and session.yaml holds peer runs
60
+ # to the day's limit, so two staff cannot wake each other forever.
47
61
  if: >-
48
- contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.sender.login) &&
49
62
  (
50
- (github.event_name == 'issue_comment' &&
51
- contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.comment.user.login) &&
52
- contains(github.event.comment.body, '%%MENTION%%')) ||
53
- (github.event_name == 'issues' &&
54
- contains(github.event.issue.body, '%%MENTION%%'))
63
+ contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.sender.login) &&
64
+ (
65
+ (github.event_name == 'issue_comment' &&
66
+ contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.comment.user.login) &&
67
+ contains(github.event.comment.body, '%%MENTION%%')) ||
68
+ (github.event_name == 'issues' &&
69
+ contains(github.event.issue.body, '%%MENTION%%'))
70
+ )
71
+ ) || (
72
+ github.event_name == 'issues' && github.event.action == 'opened' &&
73
+ endsWith(github.event.sender.login, '[bot]') &&
74
+ github.event.sender.login != '%%APP%%[bot]' &&
75
+ contains(join(github.event.issue.labels.*.name, ','), 'from-')
55
76
  )
77
+ # The ceiling on what session.yaml's job token may do: reading the checkout, and the one
78
+ # comment that says a run failed when the App that would normally say so is what broke.
79
+ # A called workflow cannot raise these, so they have to be granted here.
80
+ #
81
+ # `actions` is for the daily limit, which counts this repo's runs today. It is `write`
82
+ # because session.yaml's job asks for that (a daily run starts its follow-on with it), and a
83
+ # called job asking for more than its caller granted fails before it starts.
84
+ permissions:
85
+ contents: read
86
+ issues: write
87
+ actions: write
56
88
  uses: %%OPS_REPO%%/.github/workflows/session.yaml@main
57
89
  with:
58
90
  staff: %%STAFF%%
59
91
  kind: mention
92
+ trigger: ${{ contains(fromJSON('%%HUMAN_LOGINS%%'), github.event.sender.login) && 'mention' || 'peer' }}
93
+ max_runs_per_day: %%MAX_RUNS%%
60
94
  ops_repo: %%OPS_REPO%%
61
95
  model: %%MODEL%%
62
96
  timeout_minutes: %%MENTION_TIMEOUT%%
@@ -11,10 +11,10 @@ between %%MENTION%% and everyone else.
11
11
  Write it before the first unattended run. A generated charter would produce a generic agent,
12
12
  which is the failure this whole arrangement exists to avoid.
13
13
 
14
- Write it with your own AI:
14
+ Write it with your own AI. This prints a brief to paste into whichever agent you use (in
15
+ Claude Code it is also /charter, from inside this repo):
15
16
 
16
- cd %%DIR%% && claude
17
- /charter
17
+ roster brief charter %%STAFF%%
18
18
 
19
19
  Or write it by hand. The headings below are the shape that has worked; the words are yours.
20
20
 
@@ -10,6 +10,7 @@ on, and has decided.
10
10
  | `memory/INDEX.md` | One line per fact, read at every boot. |
11
11
  | `memory/notes/` | The argument behind a fact, read on demand. |
12
12
  | `log/decisions.md` | Why things were decided. Not boot context. |
13
+ | `strategy/` | Longer role documents, and `ideas.md`: ideas parked here rather than filed as issues. |
13
14
  | `.github/workflows/` | Three callers. The body lives in `%%OPS_REPO%%`. |
14
15
 
15
16
  Scheduled runs and mentions are wired up by roster. To see what this staff member is actually
@@ -4,3 +4,6 @@ Why things were decided, newest first. Not boot context: this is read when a dec
4
4
  being revisited, not every morning.
5
5
 
6
6
  One entry per decision. What was decided, why, and what would change it back.
7
+
8
+ This file holds the current month. Move anything older into `log/decisions/<YYYY-MM>.md`:
9
+ `roster lint` warns past 24KB.
@@ -13,6 +13,9 @@ schedule: "%%SCHEDULE%%"
13
13
  model: %%MODEL%%
14
14
  timeout_minutes: %%TIMEOUT%%
15
15
  mention_timeout_minutes: %%MENTION_TIMEOUT%%
16
+ # Runs a day that start without a person asking: a peer's ask, or a follow-on to a daily run.
17
+ # Mentions never count against it.
18
+ max_runs_per_day: %%MAX_RUNS%%
16
19
 
17
20
  bot: %%APP%%[bot]
18
21
  public_bot: %%PUBLIC_APP%%[bot]
@@ -40,4 +43,4 @@ surfaces:
40
43
 
41
44
  labels:
42
45
  owner: [%%HUMAN_MARKER%%, %%STAFF%%]
43
- kind: [decision, setup, build, blocked]
46
+ kind: [decision, review, chore, keep-open, build, blocked]
@@ -0,0 +1,7 @@
1
+ # Ideas
2
+
3
+ Speculative ideas, one line each, parked here rather than filed as issues. An issue is for
4
+ something that needs a ruling; an idea that does not yet is noise on the tracker.
5
+
6
+ Promote one to an issue when it serves a priority in `org/priorities.md` and needs a ruling.
7
+ Delete one when it stops being interesting.
@@ -0,0 +1,46 @@
1
+ Write `org/priorities.md` for %%ORG_NAME%%.
2
+
3
+ You are helping %%HUMAN%% decide what their AI staff should work on this month. Every staff
4
+ member reads this file at the start of every run and picks work that serves it, so a vague
5
+ priority produces scattered work.
6
+
7
+ ## Where you are
8
+
9
+ - `%%OPS_REPO_DIR%%/org/business.md`: what the business is. **Read it first**, and don't ask
10
+ anything it already answers.
11
+ - `%%OPS_REPO_DIR%%/org/priorities.md`: the current file, which you are replacing.
12
+
13
+ If you cannot read files where you are running, ask %%HUMAN%% to paste `org/business.md`.
14
+
15
+ ## Interview
16
+
17
+ Ask one question at a time. You are after:
18
+
19
+ - **The one outcome that matters most this month**, and how they will know it happened.
20
+ - **At most two more**, in order. Push back on a fourth: past three it is a wish list.
21
+ - **What is out of scope this month**: work that is tempting but not now. Naming it is what
22
+ stops the staff doing it.
23
+
24
+ Prefer outcomes ("a stranger pays for it") to activities ("improve the landing page"). If an
25
+ answer is an activity, ask what it is for.
26
+
27
+ ## Write it
28
+
29
+ Use exactly this shape:
30
+
31
+ ```
32
+ ## What matters this month
33
+
34
+ ### Priorities, in order
35
+
36
+ 1. The first outcome, and how you will know it happened.
37
+ 2. The second.
38
+ 3. The third.
39
+
40
+ ### Out of scope this month
41
+
42
+ - One thing per line.
43
+ ```
44
+
45
+ Keep each priority to a sentence or two. Don't add anything %%HUMAN%% didn't say without
46
+ listing it after the file so they can check it.