@nanocollective/roster 0.1.0-alpha.1

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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/cli.js +5679 -0
  4. package/docs/README.md +99 -0
  5. package/docs/agents.md +163 -0
  6. package/docs/architecture.md +121 -0
  7. package/docs/commands.md +223 -0
  8. package/docs/concepts.md +112 -0
  9. package/docs/cost.md +61 -0
  10. package/docs/developing.md +147 -0
  11. package/docs/doctor-codes.md +74 -0
  12. package/docs/export.md +113 -0
  13. package/docs/extending.md +97 -0
  14. package/docs/getting-started.md +134 -0
  15. package/docs/hosting.md +72 -0
  16. package/docs/manual-steps.md +163 -0
  17. package/docs/memory.md +71 -0
  18. package/docs/org-yaml.md +143 -0
  19. package/docs/portal.md +342 -0
  20. package/docs/prompts.md +133 -0
  21. package/docs/security.md +122 -0
  22. package/docs/session-workflow.md +112 -0
  23. package/docs/staff-yaml.md +163 -0
  24. package/docs/troubleshooting.md +189 -0
  25. package/docs/upgrading.md +83 -0
  26. package/docs/writing-a-charter.md +83 -0
  27. package/package.json +60 -0
  28. package/templates/brain/.github/workflows/%%STAFF%%-daily.yaml +33 -0
  29. package/templates/brain/.github/workflows/%%STAFF%%-mention.yaml +65 -0
  30. package/templates/brain/.github/workflows/%%STAFF%%-pr-mention.yaml +50 -0
  31. package/templates/brain/CHARTER.md +49 -0
  32. package/templates/brain/README.md +18 -0
  33. package/templates/brain/drafts/README.md +7 -0
  34. package/templates/brain/log/decisions.md +6 -0
  35. package/templates/brain/memory/INDEX.md +28 -0
  36. package/templates/brain/staff.yaml +44 -0
  37. package/templates/brain/strategy/README.md +7 -0
  38. package/templates/briefs/amend.md +60 -0
  39. package/templates/briefs/charter.md +47 -0
  40. package/templates/briefs/discover.md +61 -0
  41. package/templates/briefs/voice.md +53 -0
  42. package/templates/ops/.github/workflows/session.yaml +333 -0
  43. package/templates/ops/agents.mjs +143 -0
  44. package/templates/ops/compose.mjs +333 -0
  45. package/templates/ops/org/guardrails.md +14 -0
  46. package/templates/ops/org/operating.md +82 -0
  47. package/templates/ops/org/voice.md +40 -0
  48. package/templates/ops/prompts/_identity.md +14 -0
  49. package/templates/ops/prompts/_paths.md +15 -0
  50. package/templates/ops/prompts/daily.md +82 -0
  51. package/templates/ops/prompts/mention.md +53 -0
  52. package/templates/ops/prompts/pr-mention.md +57 -0
  53. package/templates/ops/runner-plan.mjs +65 -0
  54. package/templates/portal/css/base.css +104 -0
  55. package/templates/portal/css/brain.css +106 -0
  56. package/templates/portal/css/diff.css +28 -0
  57. package/templates/portal/css/graph.css +34 -0
  58. package/templates/portal/css/health.css +41 -0
  59. package/templates/portal/css/inbox.css +79 -0
  60. package/templates/portal/css/layout.css +98 -0
  61. package/templates/portal/css/markdown.css +54 -0
  62. package/templates/portal/css/setup.css +106 -0
  63. package/templates/portal/index.html +55 -0
  64. package/templates/portal/js/api.js +74 -0
  65. package/templates/portal/js/app.js +282 -0
  66. package/templates/portal/js/dialog.js +70 -0
  67. package/templates/portal/js/dom.js +106 -0
  68. package/templates/portal/js/icons.js +94 -0
  69. package/templates/portal/js/md.js +386 -0
  70. package/templates/portal/js/refresh.js +59 -0
  71. package/templates/portal/js/router.js +20 -0
  72. package/templates/portal/js/state.js +160 -0
  73. package/templates/portal/js/textdiff.js +96 -0
  74. package/templates/portal/js/views/app.js +128 -0
  75. package/templates/portal/js/views/brain.js +260 -0
  76. package/templates/portal/js/views/changed.js +157 -0
  77. package/templates/portal/js/views/checklist.js +87 -0
  78. package/templates/portal/js/views/docs.js +84 -0
  79. package/templates/portal/js/views/files.js +95 -0
  80. package/templates/portal/js/views/graph.js +436 -0
  81. package/templates/portal/js/views/health.js +158 -0
  82. package/templates/portal/js/views/inbox.js +549 -0
  83. package/templates/portal/js/views/memory.js +135 -0
  84. package/templates/portal/js/views/org.js +175 -0
  85. package/templates/portal/js/views/paste.js +142 -0
  86. package/templates/portal/js/views/prompt.js +412 -0
  87. package/templates/portal/js/views/repos.js +92 -0
  88. package/templates/portal/js/views/setup.js +344 -0
  89. package/templates/portal/js/views/staff.js +290 -0
@@ -0,0 +1,33 @@
1
+ name: %%STAFF_UPPER%% daily run
2
+
3
+ # Generated by roster. The body lives in %%OPS_REPO%%/.github/workflows/session.yaml.
4
+ # Edit this file only to change the schedule; everything else belongs in the ops repo, where
5
+ # one change reaches every staff member.
6
+ #
7
+ # NOTE: %%TOKENS%% are filled by `roster hire`; GitHub's own ${{ }} are left alone.
8
+
9
+ on:
10
+ schedule:
11
+ - cron: "%%SCHEDULE%%"
12
+ workflow_dispatch:
13
+
14
+ # A second run while one is in flight would fight it over the tracker and the branch state.
15
+ concurrency:
16
+ group: %%STAFF%%-session
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ session:
21
+ uses: %%OPS_REPO%%/.github/workflows/session.yaml@main
22
+ with:
23
+ staff: %%STAFF%%
24
+ kind: daily
25
+ ops_repo: %%OPS_REPO%%
26
+ model: %%MODEL%%
27
+ timeout_minutes: %%TIMEOUT%%
28
+ secrets:
29
+ APP_ID: ${{ secrets.%%SECRET_PREFIX%%_APP_ID }}
30
+ APP_PRIVATE_KEY: ${{ secrets.%%SECRET_PREFIX%%_APP_PRIVATE_KEY }}
31
+ PUBLIC_APP_ID: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_ID }}
32
+ PUBLIC_APP_PRIVATE_KEY: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_PRIVATE_KEY }}
33
+ AGENT_TOKEN: ${{ secrets.%%AGENT_SECRET%% }}
@@ -0,0 +1,65 @@
1
+ name: %%STAFF_UPPER%% on a mention
2
+
3
+ # Generated by roster. The body lives in %%OPS_REPO%%/.github/workflows/session.yaml.
4
+ #
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
7
+ # goes in the thread.
8
+ #
9
+ # NOTE: %%TOKENS%% are filled by `roster hire`. GitHub's own ${{ }} expressions are left alone.
10
+
11
+ on:
12
+ # A mention in the body of a brand new issue, which is often the faster route: one box, rather
13
+ # than a "create, then comment" round trip. `edited` doubles as the way to re-ask without
14
+ # opening a second issue.
15
+ issues:
16
+ types: [opened, edited]
17
+
18
+ # `edited` is the re-run handle. A re-run from the Actions tab is pinned to the workflow file as
19
+ # it was when the run started, so it can never pick up a fix, and deleting and reposting a
20
+ # comment loses its attachments. Editing fires a fresh event against the default branch's
21
+ # current file with the comment and its uploads intact.
22
+ issue_comment:
23
+ types: [created, edited]
24
+
25
+ # Per issue, not global. Several comments in a row are the normal case and a shared group would
26
+ # silently drop all but one of them.
27
+ concurrency:
28
+ group: %%STAFF%%-mention-${{ github.event.issue.number }}
29
+ cancel-in-progress: false
30
+
31
+ jobs:
32
+ answer:
33
+ # Only the human, only on a real mention. A bot quoting the phrase must never wake the loop.
34
+ #
35
+ # The outer gate is on `sender` — the account that performed the action — and not on the author
36
+ # of the thing it acted on. That distinction is load-bearing on the `issues` route: the pinned
37
+ # status issue is opened by the human and then edited by this staff member on every run, so an
38
+ # author check would let the agent's own edit wake another run, which would edit it again.
39
+ #
40
+ # One spelling of the mention is enough: GitHub's `contains` is documented as not case
41
+ # sensitive, so this already matches an uppercase mention at the start of a sentence.
42
+ if: >-
43
+ github.event.sender.login == '%%HUMAN%%' &&
44
+ (
45
+ (github.event_name == 'issue_comment' &&
46
+ github.event.comment.user.login == '%%HUMAN%%' &&
47
+ contains(github.event.comment.body, '%%MENTION%%')) ||
48
+ (github.event_name == 'issues' &&
49
+ contains(github.event.issue.body, '%%MENTION%%'))
50
+ )
51
+ uses: %%OPS_REPO%%/.github/workflows/session.yaml@main
52
+ with:
53
+ staff: %%STAFF%%
54
+ kind: mention
55
+ ops_repo: %%OPS_REPO%%
56
+ model: %%MODEL%%
57
+ timeout_minutes: %%MENTION_TIMEOUT%%
58
+ issue_number: ${{ github.event.issue.number }}
59
+ comment_id: ${{ github.event.comment.id }}
60
+ secrets:
61
+ APP_ID: ${{ secrets.%%SECRET_PREFIX%%_APP_ID }}
62
+ APP_PRIVATE_KEY: ${{ secrets.%%SECRET_PREFIX%%_APP_PRIVATE_KEY }}
63
+ PUBLIC_APP_ID: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_ID }}
64
+ PUBLIC_APP_PRIVATE_KEY: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_PRIVATE_KEY }}
65
+ AGENT_TOKEN: ${{ secrets.%%AGENT_SECRET%% }}
@@ -0,0 +1,50 @@
1
+ name: %%STAFF_UPPER%% on a product PR
2
+
3
+ # Generated by roster. The body lives in %%OPS_REPO%%/.github/workflows/session.yaml.
4
+ #
5
+ # Amends an open PR on the product repo in response to a review comment, so the human can ask for
6
+ # changes where they are already reading the diff instead of opening a ticket and cross-referencing.
7
+ #
8
+ # Not triggered directly. A forwarder in the PUBLIC product repo catches the mention and dispatches
9
+ # here. The split exists because that repo is public: its Actions logs are world readable, so the
10
+ # run that prints a charter and a chain of reasoning has to happen in a repo only we can see.
11
+ #
12
+ # NOTE: %%TOKENS%% are filled by `roster hire`. GitHub's own ${{ }} expressions are left alone.
13
+
14
+ on:
15
+ repository_dispatch:
16
+ types: [pr-mention]
17
+
18
+ # Manual handle, for testing without leaving a comment on a public PR, and for re-running a
19
+ # request the dispatcher already consumed.
20
+ workflow_dispatch:
21
+ inputs:
22
+ pr:
23
+ description: "PR number on the product repo"
24
+ required: true
25
+ comment_id:
26
+ description: "id of the comment that triggered this"
27
+ required: true
28
+
29
+ # Per PR. Several review comments in a row are the normal case; different PRs never contend.
30
+ concurrency:
31
+ group: %%STAFF%%-pr-${{ github.event.inputs.pr || github.event.client_payload.pr }}
32
+ cancel-in-progress: false
33
+
34
+ jobs:
35
+ amend:
36
+ uses: %%OPS_REPO%%/.github/workflows/session.yaml@main
37
+ with:
38
+ staff: %%STAFF%%
39
+ kind: pr-mention
40
+ ops_repo: %%OPS_REPO%%
41
+ model: %%MODEL%%
42
+ timeout_minutes: %%PR_MENTION_TIMEOUT%%
43
+ pr_number: ${{ github.event.inputs.pr || github.event.client_payload.pr }}
44
+ comment_id: ${{ github.event.inputs.comment_id || github.event.client_payload.comment_id }}
45
+ secrets:
46
+ APP_ID: ${{ secrets.%%SECRET_PREFIX%%_APP_ID }}
47
+ APP_PRIVATE_KEY: ${{ secrets.%%SECRET_PREFIX%%_APP_PRIVATE_KEY }}
48
+ PUBLIC_APP_ID: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_ID }}
49
+ PUBLIC_APP_PRIVATE_KEY: ${{ secrets.%%PUBLIC_SECRET_PREFIX%%_APP_PRIVATE_KEY }}
50
+ AGENT_TOKEN: ${{ secrets.%%AGENT_SECRET%% }}
@@ -0,0 +1,49 @@
1
+ # Charter — %%ORG_NAME%%'s %%NAME%%
2
+
3
+ **This file is a stub, and it is the most important file in this repo.**
4
+
5
+ The charter is the personality. It decides what this staff member does when nobody is
6
+ watching, what it refuses, and what it escalates. Nothing else supplies it: the shared half —
7
+ how anyone here operates, how we write, the guardrails everyone is bound by — already lives in
8
+ `%%OPS_REPO%%/org/` and is composed into every prompt. This file is only the difference
9
+ between %%MENTION%% and everyone else.
10
+
11
+ Write it before the first unattended run. A generated charter would produce a generic agent,
12
+ which is the failure this whole arrangement exists to avoid.
13
+
14
+ Write it with your own AI:
15
+
16
+ cd %%DIR%% && claude
17
+ /charter
18
+
19
+ Or write it by hand. The headings below are the shape that has worked; the words are yours.
20
+
21
+ ---
22
+
23
+ ## Who I am
24
+
25
+ One paragraph. What this role is for, in this business specifically.
26
+
27
+ ## The mission (north star)
28
+
29
+ The single thing this staff member is optimising. If a decision does not serve it, it is
30
+ somebody else's decision.
31
+
32
+ ## How I work, that others here do not
33
+
34
+ The habits particular to this role. Not the shared operating contract — that is in
35
+ `org/operating.md` and is inherited.
36
+
37
+ ## Decision rights
38
+
39
+ What this staff member decides alone, what it proposes and waits on, and what it never
40
+ touches. Be specific: a vague boundary is one that gets crossed at 07:00 on a Tuesday.
41
+
42
+ ## Guardrails on top of the org's
43
+
44
+ Only the additions. `org/guardrails.md` is already binding on everyone.
45
+
46
+ ## Where the rest of it lives
47
+
48
+ Point at `memory/INDEX.md`, `log/decisions.md`, the pinned status issue, and whatever
49
+ surfaces this role declares in `staff.yaml`.
@@ -0,0 +1,18 @@
1
+ # %%NAME%%
2
+
3
+ %%MENTION%%'s brain. This repo *is* the memory: everything this staff member knows, is working
4
+ on, and has decided.
5
+
6
+ | Where | What |
7
+ |---|---|
8
+ | `CHARTER.md` | The personality. Hand-written. Decides everything else. |
9
+ | `staff.yaml` | The machine-readable half of the charter. |
10
+ | `memory/INDEX.md` | One line per fact, read at every boot. |
11
+ | `memory/notes/` | The argument behind a fact, read on demand. |
12
+ | `log/decisions.md` | Why things were decided. Not boot context. |
13
+ | `.github/workflows/` | Three callers. The body lives in `%%OPS_REPO%%`. |
14
+
15
+ Scheduled runs and mentions are wired up by roster. To see what this staff member is actually
16
+ sent at 07:00:
17
+
18
+ roster prompt %%STAFF%% --kind daily
@@ -0,0 +1,7 @@
1
+ # Drafts
2
+
3
+ Work in progress, and specs for things not built yet. A draft is allowed to be long, unsure,
4
+ and wrong — that is what separates it from memory.
5
+
6
+ When a draft settles into something true, cut the one-line version into `memory/INDEX.md` and
7
+ leave the reasoning here.
@@ -0,0 +1,6 @@
1
+ # Decisions
2
+
3
+ Why things were decided, newest first. Not boot context: this is read when a decision is
4
+ being revisited, not every morning.
5
+
6
+ One entry per decision. What was decided, why, and what would change it back.
@@ -0,0 +1,28 @@
1
+ # Memory index
2
+
3
+ **This is %%NAME%%'s memory. Read it at every boot, in full. It is the only file that is.**
4
+
5
+ One line per fact. The line is the fact; `So:` is what it changes. A few carry a note in
6
+ `notes/` where the argument is load-bearing and worth not re-deriving. Read a note only when
7
+ the fact is in play today.
8
+
9
+ **The five rules that keep this file usable:**
10
+
11
+ 1. **One line per fact.** If it needs more, the extra goes in `notes/<slug>.md` and the line stays one line.
12
+ 2. **Correct in place. Never append "updated:".** An update chain is how one fact became six paragraphs.
13
+ 3. **Every fact says what it changes.** If you cannot write the `So:`, it is not memory. Do not add it.
14
+ 4. **Measurements carry `n` and a date. Constraints do not expire; measurements do.** Anything with a `review:` date is re-read or deleted on that date.
15
+ 5. **Deleting is the maintenance.** Cut every line that no longer changes a decision, and log the cut in `log/decisions.md`. A memory that only grows is a memory nobody reads.
16
+
17
+ The grammar, which `roster lint` enforces:
18
+
19
+ - **`<slug>`** · [<%%HUMAN_MARKER%%|measured|derived>] <the fact, one line>. **So:** <what it changes>. · [note](notes/<slug>.md)
20
+
21
+ `log/decisions.md` = why things were decided. The pinned status issue = what is outstanding.
22
+ **Nothing is copied between them.**
23
+
24
+ ---
25
+
26
+ ## Ungrouped
27
+
28
+ *No facts yet. The first session adds them. An empty memory is honest; an invented one is not.*
@@ -0,0 +1,44 @@
1
+ # %%NAME%%'s manifest. The machine-readable half of CHARTER.md.
2
+ # `roster lint` fails if this and the charter disagree.
3
+ #
4
+ # NOTE: %%TOKENS%% are filled by `roster hire`.
5
+
6
+ handle: %%STAFF%%
7
+ name: %%NAME%%
8
+ mention: "%%MENTION%%"
9
+ brain: %%BRAIN%%
10
+ status_issue: %%STATUS_ISSUE%%
11
+
12
+ schedule: "%%SCHEDULE%%"
13
+ model: %%MODEL%%
14
+ timeout_minutes: %%TIMEOUT%%
15
+ mention_timeout_minutes: %%MENTION_TIMEOUT%%
16
+ pr_mention_timeout_minutes: %%PR_MENTION_TIMEOUT%%
17
+
18
+ bot: %%APP%%[bot]
19
+ public_bot: %%PUBLIC_APP%%[bot]
20
+ public_token_env: %%PUBLIC_TOKEN_ENV%%
21
+ # The repo secret holding this staff member's coding-agent credential.
22
+ agent_secret: %%AGENT_SECRET%%
23
+
24
+ identities:
25
+ - { app: %%APP%%, secret_prefix: %%SECRET_PREFIX%%, scope: private }
26
+ - { app: %%PUBLIC_APP%%, secret_prefix: %%PUBLIC_SECRET_PREFIX%%, scope: public }
27
+
28
+ # Repos this staff member contributes to but does not own.
29
+ works_in:%%WORKS_IN%%
30
+
31
+ # Written by `roster hire`, both ways: every existing staff member gains an entry for this
32
+ # one, and this one gains an entry for each of them.
33
+ peers: []
34
+
35
+ # What the portal renders, and what this staff member is expected to keep.
36
+ surfaces:
37
+ - { path: memory/, render: memory }
38
+ - { path: strategy/, render: doc }
39
+ - { path: drafts/, render: doc }
40
+ - { path: log/, render: doc }
41
+
42
+ labels:
43
+ owner: [%%HUMAN_MARKER%%, %%STAFF%%]
44
+ kind: [decision, setup, build, blocked]
@@ -0,0 +1,7 @@
1
+ # Strategy
2
+
3
+ The detail behind a fact. When `memory/INDEX.md` says *what* is true in one line, the working
4
+ that got there lives here.
5
+
6
+ Not boot context: a strategy document is read when its subject is in play, not every morning.
7
+ If something in here changes a decision, the one-line version belongs in memory with a `So:`.
@@ -0,0 +1,60 @@
1
+ Change what %%NAME%% is told to do.
2
+
3
+ You are helping %%HUMAN%% amend the prompt that %%NAME%% (%%MENTION%%) at %%ORG_NAME%% runs on.
4
+ Everything you need is in this message: the prompt as it is composed today, and every file it
5
+ is assembled from. You do not need to ask for any of it.
6
+
7
+ ## What is wanted
8
+
9
+ %%WANT%%
10
+
11
+ ## How this prompt is assembled
12
+
13
+ The text an agent receives is composed at run time from several files across two repositories.
14
+ No single file is the prompt. A `{{> path}}` line pulls another file in where it stands, so
15
+ the composed text is the whole tree flattened, in order.
16
+
17
+ The consequence that matters: **the same change can be made in more than one place, and the
18
+ places have different blast radius.** A rule in `%%OPS_REPO_DIR%%/org/voice.md` reaches every
19
+ staff member on their next run. The same rule in `%%DIR%%/prompts/work.md` reaches only
20
+ %%NAME%%. Choosing wrong is how one person's preference becomes everyone's problem.
21
+
22
+ ## What you may change
23
+
24
+ | File | Reaches |
25
+ |---|---|
26
+ | `%%OPS_REPO_DIR%%/org/*.md` | every staff member, next run |
27
+ | `%%OPS_REPO_DIR%%/prompts/*.md` | every staff member, next run |
28
+ | `%%DIR%%/CHARTER.md` | %%NAME%% only |
29
+ | `%%DIR%%/prompts/*.md` | %%NAME%% only |
30
+
31
+ ## What you may not change
32
+
33
+ - `staff.yaml` and `org.yaml` — the machine-readable half. Wrong values here stop the prompt
34
+ composing at all, and `roster lint` and `roster doctor` are what change them safely.
35
+ - `.github/workflows/` anywhere — the agents cannot push these and neither should you.
36
+ - `memory/INDEX.md` — the agent's own working memory. It rewrites that file itself every run,
37
+ so a hand edit is writing over something about to be replaced.
38
+ - `compose.mjs`, `agents.mjs`, `session.yaml` — framework files, vendored into the tenant.
39
+ Fixing one here is lost on the next `roster upgrade`.
40
+
41
+ If what is wanted needs one of these, say so and stop. Do not work around it.
42
+
43
+ ## How to make the change
44
+
45
+ 1. **Say which file, and why that one.** Prefer the narrowest file that achieves it. If the
46
+ change is about %%NAME%% specifically, it does not belong in `org/`.
47
+ 2. **Show a diff, not a rewritten file.** %%HUMAN%% has to be able to see exactly what moved.
48
+ 3. **Do not restate.** Every layer is already in the composed text below. A rule added to
49
+ `org/voice.md` that `org/operating.md` already states makes the prompt longer and no
50
+ clearer.
51
+ 4. **Cut before you add.** This text is read in full on every run forever. If you are adding a
52
+ paragraph, find one to remove.
53
+ 5. **Check the composed result.** Say what the composed prompt will read like after the change,
54
+ and name anything it now contradicts.
55
+ 6. `org/voice.md` binds these files too. Write in that voice.
56
+
57
+ ## Then
58
+
59
+ Give %%HUMAN%% the diff, the one-line reason for the file you chose, and what you cut. They
60
+ apply it: in the portal's Prompt screen, or by editing the file and committing it.
@@ -0,0 +1,47 @@
1
+ Write or revise `CHARTER.md` for %%NAME%%.
2
+
3
+ You are helping %%HUMAN%% author the charter for %%NAME%% (%%MENTION%%) at %%ORG_NAME%%. This
4
+ is the file that decides everything else about how this staff member behaves.
5
+
6
+ ## Where you are
7
+
8
+ The workspace holds the ops repo and every brain repo side by side. You are writing
9
+ `%%DIR%%/CHARTER.md`.
10
+
11
+ If you cannot read files where you are running, ask %%HUMAN%% to paste the files below.
12
+
13
+ ## Read first, in this order
14
+
15
+ 1. `../%%OPS_REPO_DIR%%/org/business.md` — what this business actually is.
16
+ 2. `../%%OPS_REPO_DIR%%/org/operating.md`, `org/voice.md`, `org/guardrails.md` — the shared
17
+ half every staff member already inherits. **Do not restate any of it.** The charter is only
18
+ the difference between this role and the others.
19
+ 3. Every peer's `CHARTER.md`, for consistency of register and to find the seams between roles.
20
+ 4. This repo's `staff.yaml` — the machine-readable half. The charter must not contradict it.
21
+
22
+ ## Then interview
23
+
24
+ Ask about the role's purpose, the decisions it owns outright, the ones it must escalate, and
25
+ what it should refuse. Ask one question at a time and follow the answers; do not present a
26
+ form.
27
+
28
+ The questions that actually matter:
29
+
30
+ - **What is this role for?** One sentence. If it needs three, the role is two roles.
31
+ - **What does it decide alone?** Be concrete: it will be acting at 07:00 with nobody awake.
32
+ - **What must it escalate?** And what should it do while it waits, since a run that stops to
33
+ ask has wasted its slot.
34
+ - **What should it refuse**, even when asked directly?
35
+ - **Where does it end and a peer begin?** Seams are where two agents do the same work twice.
36
+
37
+ ## Then write it
38
+
39
+ Draft `CHARTER.md` from what they tell you. Then check it yourself:
40
+
41
+ - Does anything here duplicate `org/`? Cut it.
42
+ - Are the decision rights specific enough to act on at 07:00 with nobody awake?
43
+ - Does it contradict `staff.yaml`? `roster lint` will fail if so.
44
+ - Does it read in the house voice? `org/voice.md` binds this file too.
45
+
46
+ Show %%HUMAN%% the draft and the list of what you cut and why. The charter is theirs, not
47
+ yours — do not commit it without them reading it.
@@ -0,0 +1,61 @@
1
+ Write `org/business.md` for %%ORG_NAME%%.
2
+
3
+ You are helping %%HUMAN%% describe their business to the AI staff who will work on it. What you
4
+ write is composed into the top of every prompt every one of them ever runs. It is the single
5
+ file standing between agents that know this company and agents that produce generic slop.
6
+
7
+ ## Where you are
8
+
9
+ The workspace holds the ops repo and every brain repo side by side:
10
+
11
+ - `%%OPS_REPO_DIR%%/` — the org layer. You are writing `%%OPS_REPO_DIR%%/org/business.md`.
12
+ - `%%OPS_REPO_DIR%%/org/operating.md`, `org/voice.md`, `org/guardrails.md` — the shared half
13
+ every staff member already inherits. **Read them.** Do not restate any of it.
14
+
15
+ If you cannot read files where you are running, ask %%HUMAN%% to paste the current
16
+ `org/business.md` stub and anything else you need.
17
+
18
+ ## Read before you ask anything
19
+
20
+ Whatever exists already: the product's README, the site, the docs, recent commits, open
21
+ issues. Come to the interview knowing what you could have found out for yourself. A question
22
+ whose answer is in the README wastes the one thing this file is spending, which is %%HUMAN%%'s
23
+ attention.
24
+
25
+ ## Then interview
26
+
27
+ Ask one question at a time and follow the answers. Do not present a form. You are after:
28
+
29
+ - **What the business does**, in one line, in %%HUMAN%%'s own words rather than marketing copy.
30
+ - **Who the customers are**, and which of them matter most right now.
31
+ - **The one fact everything follows from.** Every business has one. It is usually the thing
32
+ they would say if you asked what is really going on. Push for it.
33
+ - **What is true today** that an agent would otherwise assume wrongly: what is built, what is
34
+ not, what shipped and disappointed, what is deliberately parked.
35
+ - **The numbers that matter**, and how to read them. An agent that cannot tell a good week
36
+ from a bad one will report both the same way.
37
+ - **What is off the table**, and why. Constraints are as load-bearing as goals.
38
+
39
+ ## Then write it
40
+
41
+ Write `org/business.md`. It is prose, not a form. Aim for something a new colleague could read
42
+ in three minutes and then be useful.
43
+
44
+ - **The first paragraph is the one fact everything follows from.** If they read only that, they
45
+ should know what to optimise for.
46
+ - **Be specific and dated.** "About 10 arrivals a day (31 Jul to 30 Aug)" beats "low traffic".
47
+ A number without a date rots silently.
48
+ - **Say what is not true.** The things an agent would otherwise assume are the expensive
49
+ mistakes.
50
+ - **No aspiration.** This file is what is, not what is hoped for. Strategy belongs in a brain.
51
+ - `org/voice.md` binds this file too. Read it and write in that voice.
52
+
53
+ ## Then check it
54
+
55
+ - Would an agent reading only this write something a customer of %%ORG_NAME%% would recognise?
56
+ - Does anything here duplicate `org/operating.md`, `org/voice.md` or `org/guardrails.md`? Cut it.
57
+ - Is every number dated?
58
+ - Is there anything you asserted that %%HUMAN%% did not actually say?
59
+
60
+ Show them the draft and what you cut. **This file is theirs, not yours.** Do not commit it
61
+ without them reading it.
@@ -0,0 +1,53 @@
1
+ Revise `org/voice.md` for %%ORG_NAME%%.
2
+
3
+ You are helping %%HUMAN%% set the house voice every AI staff member writes in. It binds every
4
+ surface they produce: issues, comments, PR bodies, run reports, briefs to each other, and how
5
+ they talk in a session. Changing this file once changes all of them on their next run.
6
+
7
+ ## Where you are
8
+
9
+ You are editing `%%OPS_REPO_DIR%%/org/voice.md`. It already exists and is already opinionated:
10
+ roster ships a version that argues for concision over word counts. **Start from what is there.**
11
+ This is a revision, not a blank page.
12
+
13
+ If you cannot read files where you are running, ask %%HUMAN%% to paste the current
14
+ `org/voice.md`.
15
+
16
+ ## Read first
17
+
18
+ 1. `%%OPS_REPO_DIR%%/org/voice.md` — what is in force today.
19
+ 2. `%%OPS_REPO_DIR%%/org/business.md` — who is being written for.
20
+ 3. A dozen real issues and comments the staff have actually written. **This is the important
21
+ one.** A voice rule that does not name a habit you can point at in the output is decoration.
22
+
23
+ ## Then interview
24
+
25
+ Ask one question at a time. What you are after is friction, not preferences:
26
+
27
+ - **What did you last read from them and wish were shorter?** Find the specific thing.
28
+ - **What do they do that you have to correct every time?**
29
+ - **What register is wrong?** Too formal, too chatty, too hedged, too certain.
30
+ - **What must never appear?** Sign-offs, apologies, recaps, options menus, emoji.
31
+ - **How do you want to be addressed?** They are writing to %%HUMAN%% far more than to anyone
32
+ else.
33
+
34
+ ## Then write it
35
+
36
+ - **Every rule names a behaviour, not a virtue.** "The first sentence is the point" is
37
+ actionable. "Be clear" is not.
38
+ - **Cut on sight lists work.** A list of things to delete is easier to obey than a list of
39
+ things to aspire to.
40
+ - **No word counts.** They are the obvious rule and the wrong one: they produce padded short
41
+ writing rather than concise writing. Say what to cut instead.
42
+ - **Keep it short.** This file is read in full on every run by every staff member. Every line
43
+ you add is paid for on every run forever.
44
+
45
+ ## Then check it
46
+
47
+ - Could you point at a real issue and say which rule it breaks?
48
+ - Does it contradict `org/operating.md` or a `CHARTER.md`?
49
+ - Is anything here already covered by `org/guardrails.md`? Guardrails are non-negotiables;
50
+ voice is style. Do not blur them.
51
+ - Has it got longer? If so, what came out?
52
+
53
+ Show %%HUMAN%% the diff and what you cut. Do not commit it without them reading it.