@nanocollective/roster 0.1.0-alpha.5 → 0.1.0-alpha.7
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.
- package/README.md +65 -84
- package/dist/cli.js +4153 -2708
- package/docs/README.md +9 -6
- package/docs/agents.md +24 -20
- package/docs/architecture.md +13 -5
- package/docs/charters/cmo.md +69 -0
- package/docs/charters/cto.md +71 -0
- package/docs/charters/support.md +60 -0
- package/docs/commands.md +81 -5
- package/docs/concepts.md +48 -14
- package/docs/cost.md +36 -1
- package/docs/developing.md +16 -21
- package/docs/doctor-codes.md +8 -2
- package/docs/extending.md +2 -2
- package/docs/getting-started.md +100 -77
- package/docs/images/brain.jpg +0 -0
- package/docs/images/org.jpg +0 -0
- package/docs/images/prompt.jpg +0 -0
- package/docs/images/setup-org.jpg +0 -0
- package/docs/images/setup-plan.jpg +0 -0
- package/docs/images/staff.jpg +0 -0
- package/docs/manual-steps.md +93 -123
- package/docs/memory.md +21 -3
- package/docs/org-yaml.md +37 -2
- package/docs/portal.md +59 -33
- package/docs/prompts.md +25 -4
- package/docs/security.md +29 -5
- package/docs/session-workflow.md +49 -17
- package/docs/staff-yaml.md +13 -2
- package/docs/troubleshooting.md +8 -8
- package/docs/upgrading.md +6 -0
- package/docs/writing-a-charter.md +15 -0
- package/package.json +1 -1
- package/templates/brain/.github/workflows/%%STAFF%%-daily.yaml +6 -0
- package/templates/brain/.github/workflows/%%STAFF%%-mention.yaml +6 -0
- package/templates/brain/CHARTER.md +3 -3
- package/templates/brain/README.md +1 -0
- package/templates/brain/log/decisions.md +3 -0
- package/templates/brain/strategy/ideas.md +7 -0
- package/templates/ops/.github/workflows/session.yaml +108 -14
- package/templates/ops/agents.mjs +7 -3
- package/templates/ops/compose.mjs +16 -3
- package/templates/ops/inflight.mjs +157 -0
- package/templates/ops/org/operating.md +21 -1
- package/templates/ops/org/voice.md +9 -0
- package/templates/ops/prompts/_inflight.md +14 -0
- package/templates/ops/prompts/_paths.md +2 -1
- package/templates/ops/prompts/daily.md +16 -7
- package/templates/ops/prompts/mention.md +2 -0
- package/templates/ops/run-record.mjs +144 -0
- package/templates/portal/css/base.css +133 -73
- package/templates/portal/css/brain.css +23 -20
- package/templates/portal/css/diff.css +10 -9
- package/templates/portal/css/graph.css +12 -7
- package/templates/portal/css/health.css +12 -10
- package/templates/portal/css/inbox.css +24 -21
- package/templates/portal/css/layout.css +64 -46
- package/templates/portal/css/markdown.css +17 -14
- package/templates/portal/css/runs.css +13 -0
- package/templates/portal/css/setup.css +38 -32
- package/templates/portal/index.html +5 -1
- package/templates/portal/js/api.js +29 -3
- package/templates/portal/js/app.js +4 -1
- package/templates/portal/js/state.js +3 -1
- package/templates/portal/js/views/app.js +23 -5
- package/templates/portal/js/views/credential.js +93 -0
- package/templates/portal/js/views/graph.js +1 -1
- package/templates/portal/js/views/health.js +15 -3
- package/templates/portal/js/views/org.js +2 -0
- package/templates/portal/js/views/paste.js +29 -0
- package/templates/portal/js/views/runonce.js +88 -0
- package/templates/portal/js/views/runs.js +165 -0
- package/templates/portal/js/views/setup.js +67 -26
- package/templates/portal/js/views/staff.js +47 -10
package/docs/manual-steps.md
CHANGED
|
@@ -1,186 +1,156 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Manual steps"
|
|
3
|
-
description: "
|
|
3
|
+
description: "What only a person can do, why, and what breaks if it is skipped."
|
|
4
4
|
sidebar_order: 2
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Manual steps
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
What roster cannot do for you, why, and what it looks like when one is skipped. The
|
|
10
|
+
[getting started](getting-started.md) path walks through each of these in order; this page is
|
|
11
|
+
what to read when one of them bites.
|
|
11
12
|
|
|
12
|
-
**
|
|
13
|
-
that
|
|
14
|
-
for items 5 and 6. This page is still the *why*: it is what to read when one of them bites, and
|
|
15
|
-
what to check when the page says something is not done.
|
|
16
|
-
|
|
17
|
-
The portal's **Health** screen checks most of these, per staff member and for the org, with
|
|
18
|
-
every finding carrying the sentence that fixes it. `roster doctor` prints the same from a
|
|
19
|
-
terminal. Look after each step.
|
|
13
|
+
**Health**, or `roster doctor`, checks each one it can, and every finding carries the sentence
|
|
14
|
+
that fixes it.
|
|
20
15
|
|
|
21
16
|
---
|
|
22
17
|
|
|
23
|
-
## 1.
|
|
24
|
-
|
|
25
|
-
**Do:** `<org>/roster-ops` -> Settings -> Actions -> General -> *Access* -> **Accessible from
|
|
26
|
-
repositories in the organisation**. The setup screen links straight to that page.
|
|
18
|
+
## 1. Create the organisation
|
|
27
19
|
|
|
28
|
-
**
|
|
29
|
-
needs admin rights that a token created for a different purpose should not have. roster reads
|
|
30
|
-
it and tells you, but setting it is one click and it is yours.
|
|
20
|
+
**Do:** make it on github.com, if you do not have one.
|
|
31
21
|
|
|
32
|
-
**
|
|
33
|
-
a path, or a missing file, or a bad branch reference. You will check all three. It is none of
|
|
34
|
-
them, it is this.
|
|
35
|
-
|
|
36
|
-
**Check:** Health, or `roster doctor`, reports `roster-ops is callable from the whole org`.
|
|
22
|
+
**Why not automated:** GitHub has no API for creating an organisation.
|
|
37
23
|
|
|
38
24
|
---
|
|
39
25
|
|
|
40
|
-
## 2.
|
|
26
|
+
## 2. Confirm the GitHub App
|
|
41
27
|
|
|
42
|
-
**Do:**
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
**Do:** press **GitHub App** on a staff card, or run `roster app <handle> --apply`. A tab
|
|
29
|
+
opens; confirm on GitHub. The App's id and private key go straight into the brain repo's
|
|
30
|
+
secrets.
|
|
45
31
|
|
|
46
|
-
**Why not
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
**Why not automated:** there is no API that creates a GitHub App. The only route is the App
|
|
33
|
+
Manifest flow, where a person confirms on a GitHub page. roster does everything either side of
|
|
34
|
+
that.
|
|
49
35
|
|
|
50
|
-
**If you skip it:** the run fails at the token-minting step
|
|
51
|
-
existing.
|
|
36
|
+
**If you skip it:** the run fails at the token-minting step, saying the App does not exist.
|
|
52
37
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
38
|
+
The private key is handed to `gh` on standard input. It is never written to a file, never on a
|
|
39
|
+
command line, and never in the process table. If the secret write fails after the App is
|
|
40
|
+
created, the key is gone: generate a new one from the App's settings page and set the secret by
|
|
41
|
+
hand. roster says so if it happens.
|
|
57
42
|
|
|
58
43
|
---
|
|
59
44
|
|
|
60
|
-
## 3.
|
|
61
|
-
|
|
62
|
-
**Do:** open the URL the portal shows, or that `roster app` prints. Choose repositories.
|
|
45
|
+
## 3. Confirm the App's install
|
|
63
46
|
|
|
64
|
-
**
|
|
65
|
-
|
|
47
|
+
**Do:** press **Install it** in the portal, or open the link `roster app` prints. The page opens
|
|
48
|
+
with the organisation and the repos this staff member needs already selected: its brain, each
|
|
49
|
+
peer's tracker, and the product repos. Check the list and confirm.
|
|
66
50
|
|
|
67
|
-
**
|
|
68
|
-
|
|
69
|
-
`roster app` say so.
|
|
51
|
+
**Why not automated:** installing is a grant of access to specific repositories, and GitHub asks
|
|
52
|
+
a person to confirm it. That is correct and should not be worked around.
|
|
70
53
|
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
The pre-selection uses `suggested_target_id` and `repository_ids[]` on the install page. GitHub's
|
|
55
|
+
own links use them, but they are not in GitHub's documentation. If the ids cannot be read, or
|
|
56
|
+
GitHub stops honouring them, the link is the plain install page and you tick the repos yourself;
|
|
57
|
+
the portal and `roster app` both list which.
|
|
73
58
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
So: **do not verify an installation by reading the API.** The only thing that proves the whole
|
|
80
|
-
chain (App created, installed, granted, secrets right, workflow reachable) is a run that
|
|
81
|
-
finished. `roster doctor` reads a window of recent runs for exactly this reason, and reports a
|
|
82
|
-
workflow that has never run as **unproven** rather than as fine.
|
|
83
|
-
|
|
84
|
-
**Check:** that staff member's Health screen, or `roster doctor <handle>`. Then trigger one run
|
|
85
|
-
and look again.
|
|
59
|
+
**If you under-grant it:** this is the trap that costs the most time, because the API reports an
|
|
60
|
+
App's **declaration** separately from an installation's **grant**. `GET /apps/<slug>` will say
|
|
61
|
+
the App exists and has `contents: write` without saying whether it is installed on the repo you
|
|
62
|
+
care about. So **do not verify an installation by reading the API**. Run it once (item 5).
|
|
86
63
|
|
|
87
64
|
---
|
|
88
65
|
|
|
89
|
-
## 4.
|
|
66
|
+
## 4. Get the agent's credential
|
|
90
67
|
|
|
91
|
-
**Do:**
|
|
92
|
-
|
|
93
|
-
|
|
68
|
+
**Do:** get a credential for your coding agent (`claude setup-token` for Claude Code; the others
|
|
69
|
+
are in [choosing a coding agent](agents.md#1-the-credential-exists-and-you-have-it)) and paste it
|
|
70
|
+
into **Agent credential**, or pipe it to `roster credential --apply`. It is stored once, as an
|
|
71
|
+
organisation secret shared with the brain repos, and each hire adds its repo to it.
|
|
94
72
|
|
|
95
73
|
**Why not automated:** it is your account's credential and roster has no way to obtain one.
|
|
96
74
|
|
|
75
|
+
Where an org secret would not arrive, it goes on each brain repo instead and says why. On GitHub
|
|
76
|
+
Free, org secrets do not reach private repos, and only an org owner can set one. Setting an org
|
|
77
|
+
secret also needs the `admin:org` scope on your `gh` token; if it is missing, the credential goes
|
|
78
|
+
on each repo and the output gives the command that adds the scope.
|
|
79
|
+
|
|
97
80
|
**If you skip it:** the run fails immediately with `the caller passed no agent credential`.
|
|
98
|
-
That check exists so it fails there rather than forty lines later inside the agent, after the
|
|
99
|
-
checkouts have already happened.
|
|
100
81
|
|
|
101
|
-
**Check:** Health, or `roster doctor`, lists the secrets each caller references and whether
|
|
102
|
-
|
|
82
|
+
**Check:** Health, or `roster doctor`, lists the secrets each caller references and whether they
|
|
83
|
+
exist, on the repo or shared from the org.
|
|
103
84
|
|
|
104
85
|
---
|
|
105
86
|
|
|
106
|
-
## 5.
|
|
87
|
+
## 5. Watch the first run
|
|
107
88
|
|
|
108
|
-
**Do:**
|
|
109
|
-
|
|
110
|
-
as an agent standing in the repo; the box beneath it takes the reply, shows you a diff, and
|
|
111
|
-
saves only when you press the button. `roster brief discover` prints the same brief for a
|
|
112
|
-
terminal, and you can always just answer the questions in the file by hand.
|
|
89
|
+
**Do:** **Run once now** on the staff card or on Health, or `roster run <handle> --apply`. It
|
|
90
|
+
starts the daily workflow, follows it, and reports how it ended, with the log.
|
|
113
91
|
|
|
114
|
-
|
|
92
|
+
**Why it is yours:** it is a real run. It does a day's work and costs what one does, so it is a
|
|
93
|
+
button you press rather than something setup does behind your back.
|
|
115
94
|
|
|
116
|
-
**Why
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
**If you skip it:** nothing errors. That is the problem. You get competent-looking output about
|
|
121
|
-
a business that does not exist.
|
|
95
|
+
**Why it matters:** the only thing that proves the whole chain (App created, installed, granted,
|
|
96
|
+
secrets right, ops repo callable) is a run that finished. `roster doctor` reports a workflow
|
|
97
|
+
that has never run as **unproven** rather than fine, and one finished run clears it.
|
|
122
98
|
|
|
123
99
|
---
|
|
124
100
|
|
|
125
|
-
## 6. Write
|
|
101
|
+
## 6. Write `org/business.md` and `org/priorities.md`
|
|
126
102
|
|
|
127
|
-
**Do:** **
|
|
128
|
-
paste
|
|
129
|
-
the
|
|
130
|
-
|
|
131
|
-
[writing a charter](writing-a-charter.md) has the shape if you would rather write it yourself.
|
|
103
|
+
**Do:** on the setup screen, **Copy the prompt** puts a brief on your clipboard with every file
|
|
104
|
+
it refers to inside it; paste the reply back and you get a diff and a save button. `roster brief
|
|
105
|
+
discover` prints the same brief. Then write `org/priorities.md`: a few ranked lines on what
|
|
106
|
+
matters this month.
|
|
132
107
|
|
|
133
|
-
|
|
134
|
-
different from the others.
|
|
108
|
+
Health reports `business.stub` and `priorities.stub` while either is still the stub.
|
|
135
109
|
|
|
136
|
-
**
|
|
137
|
-
|
|
138
|
-
whatever the shared layer implies.
|
|
110
|
+
**Why not automated:** an agent that does not know the business writes work that is plausible
|
|
111
|
+
and generic. That is worse than no work, because it takes longer to notice.
|
|
139
112
|
|
|
140
|
-
|
|
113
|
+
**If you skip it:** nothing errors. That is the problem.
|
|
141
114
|
|
|
142
|
-
|
|
115
|
+
---
|
|
143
116
|
|
|
144
|
-
|
|
145
|
-
upgrade`, which writes into repos on disk and leaves them for you. Review, commit, push.
|
|
117
|
+
## 7. Write each staff member's `CHARTER.md`
|
|
146
118
|
|
|
147
|
-
|
|
148
|
-
|
|
119
|
+
**Do:** **Write the charter** on that staff member's card, the same round trip as item 6. The
|
|
120
|
+
brief carries the org layer, `business.md`, the peers' charters, and where the role matches one,
|
|
121
|
+
a [worked example](writing-a-charter.md#worked-examples) to model the shape on. `roster brief
|
|
122
|
+
charter <handle>` prints the same brief.
|
|
149
123
|
|
|
150
|
-
**Why not automated:**
|
|
151
|
-
|
|
152
|
-
repository**, which is a GitHub restriction and not a configuration mistake. That is also why
|
|
153
|
-
agents can never update their own workflows, and why upgrades are human-run by design.
|
|
124
|
+
**Why not automated:** the charter is what makes a staff member different from the others, and
|
|
125
|
+
a generated one is the generic agent this arrangement exists to avoid.
|
|
154
126
|
|
|
155
|
-
**If you skip it:**
|
|
156
|
-
|
|
127
|
+
**If you skip it:** `charter.stub` says nobody has answered it, and the agent produces whatever
|
|
128
|
+
the shared layer implies.
|
|
157
129
|
|
|
158
130
|
---
|
|
159
131
|
|
|
160
|
-
##
|
|
132
|
+
## 8. Commit what `roster upgrade` wrote
|
|
133
|
+
|
|
134
|
+
**Do:** review, commit and push what `roster upgrade --apply` changed in the brain repos.
|
|
161
135
|
|
|
162
|
-
|
|
136
|
+
**Why not automated:** **App tokens cannot push a change under `.github/workflows/`**, in any
|
|
137
|
+
repository. That is a GitHub restriction, and it is why agents never update their own workflows
|
|
138
|
+
and upgrades are run by a person. Hiring commits its own changes as you, and lists them first.
|
|
163
139
|
|
|
164
|
-
|
|
140
|
+
**If you skip it:** the change exists locally and nowhere else, and `roster upgrade` reports it as
|
|
141
|
+
pending next time.
|
|
165
142
|
|
|
166
|
-
|
|
167
|
-
the setup screen 1 is deep-linked from it, and 5 is on it
|
|
168
|
-
Staff -> Hire someone then 7
|
|
169
|
-
GitHub App, on the new staff card 2, then 3
|
|
170
|
-
Write the charter, on the same card 6
|
|
171
|
-
4 is yours: a secret on the brain repo
|
|
172
|
-
Health until the ids are gone
|
|
173
|
-
```
|
|
143
|
+
---
|
|
174
144
|
|
|
175
|
-
|
|
145
|
+
## What roster does for you
|
|
176
146
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
roster hire <handle> --apply # then 7
|
|
180
|
-
roster app <handle> # 2, then 3
|
|
181
|
-
# 4, 5, 6
|
|
182
|
-
roster doctor <handle>
|
|
183
|
-
```
|
|
147
|
+
Each of these is a step of a command, listed in its plan before it happens, and each falls back
|
|
148
|
+
to telling you exactly what to click if GitHub refuses.
|
|
184
149
|
|
|
185
|
-
|
|
186
|
-
|
|
150
|
+
| | |
|
|
151
|
+
|---|---|
|
|
152
|
+
| The ops repo's Actions access | `roster init --apply`, or **Set it for me** on the setup screen. Needs admin on the ops repo. Skipped, every caller fails with "workflow not found". |
|
|
153
|
+
| Committing peer wiring | `roster hire --apply` commits and pushes each peer's `staff.yaml` and `org.yaml` as you. A push that fails is reported and left for you. |
|
|
154
|
+
| Giving each new brain the credential | `roster hire --apply` adds the repo to the org secret. |
|
|
155
|
+
| Choosing repos on the install page | pre-selected, as above. |
|
|
156
|
+
| The review gate on product repos | `roster hire --apply` adds it where there is none. See [security](security.md#the-review-gate). |
|
package/docs/memory.md
CHANGED
|
@@ -16,8 +16,8 @@ memory/INDEX.md one line per fact. Read in full at every boot.
|
|
|
16
16
|
memory/notes/*.md the argument behind a fact. Read only when that fact is in play.
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
That split is the whole design. Boot context here went from about 52,000 words to about
|
|
20
|
-
by making it, and the saving repeats on every run forever.
|
|
19
|
+
That split is the whole design. Boot context here went from about 52,000 words to about 10,000
|
|
20
|
+
today by making it, and the saving repeats on every run forever.
|
|
21
21
|
|
|
22
22
|
## The grammar
|
|
23
23
|
|
|
@@ -48,10 +48,27 @@ rumour.
|
|
|
48
48
|
Rule 5 is the one that gets skipped and the one that matters. Everything else degrades slowly;
|
|
49
49
|
this one degrades the boot cost of every future run.
|
|
50
50
|
|
|
51
|
+
## Budgets
|
|
52
|
+
|
|
53
|
+
Prose is advice, and an index nobody prunes grows past what a run can usefully read. So
|
|
54
|
+
`roster lint` warns past three budgets:
|
|
55
|
+
|
|
56
|
+
| Budget | Default | Rule |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| One fact's line | 400 characters | `too-long`, naming the fact |
|
|
59
|
+
| `memory/INDEX.md` | 24KB | `index-too-big`, naming the three longest facts |
|
|
60
|
+
| `log/decisions.md` | 24KB | `decisions-too-big`: roll older entries into `log/decisions/<YYYY-MM>.md` |
|
|
61
|
+
|
|
62
|
+
Change them under `memory:` in [org.yaml](org-yaml.md#memory), or per staff member in
|
|
63
|
+
[staff.yaml](staff-yaml.md#memory). The daily prompt tells a staff member to check its sizes at
|
|
64
|
+
hand-off and make pruning that run's job when it is over.
|
|
65
|
+
|
|
51
66
|
## What does not go in memory
|
|
52
67
|
|
|
53
68
|
- **Why something was decided.** That is `log/decisions.md`, and it is not boot context.
|
|
54
69
|
- **How a thing works.** That is a draft or a strategy document.
|
|
70
|
+
- **An idea not yet acted on.** That is one line in `strategy/ideas.md`, and it becomes an issue
|
|
71
|
+
only when it needs a ruling.
|
|
55
72
|
- **What is outstanding.** That is the pinned status issue.
|
|
56
73
|
|
|
57
74
|
Nothing is copied between them. Four places, four jobs, and a fact that appears in two of them
|
|
@@ -64,7 +81,8 @@ opens an issue in that staff member's own repository asking them to fix it, whic
|
|
|
64
81
|
right move: they wrote it, and an issue on their tracker is a thing that wakes them.
|
|
65
82
|
|
|
66
83
|
It catches: a missing `So:`, a duplicate slug, a note nothing links to, a link to a note that
|
|
67
|
-
does not exist, an over-long line, a `[measured]` fact with no `n`,
|
|
84
|
+
does not exist, an over-long line, a `[measured]` fact with no `n`, an "updated:" chain, and an
|
|
85
|
+
index or decision log over its budget.
|
|
68
86
|
|
|
69
87
|
The same checks, for a terminal or for CI:
|
|
70
88
|
|
package/docs/org-yaml.md
CHANGED
|
@@ -34,10 +34,12 @@ agent:
|
|
|
34
34
|
permissions: full
|
|
35
35
|
|
|
36
36
|
defaults:
|
|
37
|
-
model: claude-opus-5
|
|
37
|
+
model: claude-opus-5-5
|
|
38
38
|
timeout_minutes: 90
|
|
39
39
|
mention_timeout_minutes: 90
|
|
40
40
|
|
|
41
|
+
budget: 300
|
|
42
|
+
|
|
41
43
|
staff:
|
|
42
44
|
- { handle: cto, dir: technology, name: Chief Technology Officer, schedule: "0 7 * * 1-5" }
|
|
43
45
|
- { handle: cmo, dir: marketing, name: Chief Marketing Officer, schedule: "40 7 * * 1-5" }
|
|
@@ -58,6 +60,7 @@ repos:
|
|
|
58
60
|
| `name` | yes | What the business is called, in prose. Appears in prompts. |
|
|
59
61
|
| `ops_dir` | no | Directory name of the ops repo in the runner checkout. Defaults to `roster-ops`. |
|
|
60
62
|
| `experiment_private` | no | Whether the fact that this org is agent-run is itself private. Read by the guardrails fragment. |
|
|
63
|
+
| `budget` | no | USD over any trailing 30 days, for the whole org. See [below](#budget). |
|
|
61
64
|
|
|
62
65
|
### `human` and `humans`
|
|
63
66
|
|
|
@@ -123,6 +126,20 @@ Fallbacks for staff members who do not set their own.
|
|
|
123
126
|
| `mention_timeout_minutes` | Ceiling on a mention run. Falls back to `timeout_minutes`, then `90`. |
|
|
124
127
|
| `allowed_tools` | Claude's own spelling of a permission level, kept because it predates `agent.permissions` and still wins for the agents that take a tool list. Nothing translates it for the others: a list written for one agent is not a permission level for another. Prefer [`agent.permissions`](agents.md#permissions), which every agent understands. |
|
|
125
128
|
|
|
129
|
+
### `memory`
|
|
130
|
+
|
|
131
|
+
Budgets `roster lint` holds every staff member's memory to. All optional; a staff member's own
|
|
132
|
+
[`memory:`](staff-yaml.md#memory) overrides these.
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
memory:
|
|
136
|
+
max_fact_chars: 400 # one fact's line in memory/INDEX.md
|
|
137
|
+
max_index_kb: 24 # the whole index, read in full at every boot
|
|
138
|
+
max_decisions_kb: 24 # log/decisions.md
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Over budget is a warning naming what to cut, never an error. See [memory](memory.md#budgets).
|
|
142
|
+
|
|
126
143
|
### `staff`
|
|
127
144
|
|
|
128
145
|
The registry. One inline map per staff member. **This is the org's view of them**; the rest
|
|
@@ -134,10 +151,26 @@ lives in their own `staff.yaml`.
|
|
|
134
151
|
| `dir` | no | Directory and repo name. Defaults to the handle. |
|
|
135
152
|
| `name` | no | Role name in prose. |
|
|
136
153
|
| `schedule` | no | Cron. Informational here; the caller workflow is what actually schedules. |
|
|
154
|
+
| `budget` | no | USD over any trailing 30 days, for this staff member alone. |
|
|
137
155
|
|
|
138
156
|
`roster hire` appends to this list. An empty list (`staff: []`) is valid and is what a fresh
|
|
139
157
|
org has.
|
|
140
158
|
|
|
159
|
+
### `budget`
|
|
160
|
+
|
|
161
|
+
A number of dollars, on the org, on a staff entry, or both:
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
budget: 300
|
|
165
|
+
staff:
|
|
166
|
+
- { handle: cto, dir: technology, name: Chief Technology Officer, budget: 200 }
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Spend over the trailing 30 days is added up from each run's record. Past a budget, `roster
|
|
170
|
+
doctor` warns and the portal's Runs screen marks the total. **Nothing stops a run.** A cap that
|
|
171
|
+
ends a session fails it after the work is done and committed, which is a false red rather than a
|
|
172
|
+
saved penny; `timeout_minutes` is the real bound. See [cost](cost.md#budgets).
|
|
173
|
+
|
|
141
174
|
### `repos`
|
|
142
175
|
|
|
143
176
|
Every repository the org owns, and what it is for.
|
|
@@ -159,7 +192,9 @@ Every repository the org owns, and what it is for.
|
|
|
159
192
|
| `runner-plan.mjs` | `org`, `staff`, and each manifest's `works_in` and `peers` |
|
|
160
193
|
| `agents.mjs` | `agent`, `staff` |
|
|
161
194
|
| `roster hire` | all of it, plus every existing manifest |
|
|
162
|
-
| `roster doctor` | all of it |
|
|
195
|
+
| `roster doctor` | all of it, including `budget` |
|
|
196
|
+
| `roster lint` | `staff`, `memory` |
|
|
197
|
+
| `roster portal` | all of it; the Runs screen reads `budget` |
|
|
163
198
|
|
|
164
199
|
## Editing it
|
|
165
200
|
|
package/docs/portal.md
CHANGED
|
@@ -18,10 +18,9 @@ Keep the repos checked out beside each other, in the same shape the runner uses.
|
|
|
18
18
|
|
|
19
19
|
## The sidebar
|
|
20
20
|
|
|
21
|
-
**The counts are right on load.** The badges beside Inbox and Pending work
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
now asks once at boot, and the Inbox screen shares that request rather than making a second one.
|
|
21
|
+
**The counts are right on load.** The badges beside Inbox and Pending work are fetched once at
|
|
22
|
+
boot, and the Inbox screen shares that request rather than making a second one. A sidebar that
|
|
23
|
+
says nothing until you look at it is not a sidebar.
|
|
25
24
|
|
|
26
25
|
While the first answer is outstanding the badge is a placeholder rather than blank, because an
|
|
27
26
|
empty badge reads as zero and zero is a different claim from "still counting". The screens
|
|
@@ -50,9 +49,15 @@ It asks GitHub which of two things this is:
|
|
|
50
49
|
nothing is written until you apply. Same `initFiles` the CLI runs, so the browser and the
|
|
51
50
|
terminal cannot disagree about what a new tenant contains.
|
|
52
51
|
|
|
53
|
-
Then
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
Then what is left. **The Actions setting**, read on arrival: if it is not set, *Set it for me*
|
|
53
|
+
asks GitHub to set it, and a refusal comes back with GitHub's reason and a link to the page to
|
|
54
|
+
click. **The agent credential**: a paste box, a line on where your agent's credential comes from,
|
|
55
|
+
and where it will be stored (one org secret shared with the brains, or each brain where an org
|
|
56
|
+
secret would not arrive, with the reason). The value goes to the local server in a POST and from
|
|
57
|
+
there to `gh` on standard input; it is never written to disk or echoed back. Until somebody is
|
|
58
|
+
hired the box says so, because nothing would read it. Then which repos the staff work in, as a
|
|
59
|
+
picker over what your `gh` can see minus what `org.yaml` already has, and a prompt for writing
|
|
60
|
+
`org/business.md`.
|
|
56
61
|
|
|
57
62
|
Nothing here stores which step you are on. Setup takes days rather than minutes: an App has to be
|
|
58
63
|
installed, a credential set, a first run finished. So the page derives its state from `roster
|
|
@@ -80,9 +85,8 @@ down with the list, so opening a thread is a render rather than a request.
|
|
|
80
85
|
silently doing nothing.
|
|
81
86
|
- **A new issue asks one question: who is it for.** One dropdown, over the staff. It goes to
|
|
82
87
|
that person's brain repo and their `@handle` is written into the body for you, because those
|
|
83
|
-
are the two things that make an issue reach an agent rather than sit there.
|
|
84
|
-
|
|
85
|
-
nobody. To file in a product repo instead, use GitHub: this form is for asking the staff for
|
|
88
|
+
are the two things that make an issue reach an agent rather than sit there. Asking for a
|
|
89
|
+
repo as well would let you pick a pair that wakes nobody. To file in a product repo instead, use GitHub: this form is for asking the staff for
|
|
86
90
|
something.
|
|
87
91
|
- **Labels are the repo's own, as toggles.** They are the labels that exist on the recipient's
|
|
88
92
|
repository, fetched from GitHub and cached. A text box was a spelling test: `from-cmo` and
|
|
@@ -149,8 +153,7 @@ of every repo to show one of them is the wrong trade.
|
|
|
149
153
|
second decision and not this button's to make. It runs `gh pr merge` as you, so a protected
|
|
150
154
|
branch, a failing required check or a merge queue behaves exactly as it would on the site.
|
|
151
155
|
|
|
152
|
-
**It does not ask how.**
|
|
153
|
-
That is a question about git rather than about the pull request in front of you, the repository
|
|
156
|
+
**It does not ask how.** Squash, merge commit or rebase is a question about git rather than about the pull request in front of you, the repository
|
|
154
157
|
has already answered it in its own settings, and on any given repository most of the answers are
|
|
155
158
|
wrong. So the repository is asked instead: squash where it is allowed, then a merge commit, then
|
|
156
159
|
rebase.
|
|
@@ -160,8 +163,8 @@ rebase.
|
|
|
160
163
|
**`@cto` on a pull request wakes nobody.** A staff member's caller workflow lives in their own
|
|
161
164
|
brain repo and gates on their handle appearing *there*; on a product repo the same mention
|
|
162
165
|
posts, renders as a chip, and does nothing. That is deliberate, for the reasons in
|
|
163
|
-
[security](security.md#trust-in-a-prompt)
|
|
164
|
-
restriction itself.
|
|
166
|
+
[security](security.md#trust-in-a-prompt). Saying so out loud is the portal's job, because a
|
|
167
|
+
silent no-op is worse than the restriction itself.
|
|
165
168
|
|
|
166
169
|
**Reply is the one box, and it handles this.** Name somebody in a reply where a comment will
|
|
167
170
|
not reach them and the offer appears under the box, ticked: *open it on their tracker too*. One
|
|
@@ -183,16 +186,30 @@ On the **Files** tab each file's heading has its own Reply, which opens the same
|
|
|
183
186
|
one file. "This bit is wrong" is what you want to say while looking at a diff, and the
|
|
184
187
|
alternative is describing in prose which of thirty files you meant.
|
|
185
188
|
|
|
186
|
-
There was briefly a second button up here called *Ask a staff member*. It did almost the same
|
|
187
|
-
thing as Reply, differing mainly in making you pick a name from a dropdown rather than typing
|
|
188
|
-
it, and nothing on the page said which one you wanted. Two ways to do one thing is worse than
|
|
189
|
-
either of them.
|
|
190
|
-
|
|
191
189
|
Both writes go through your own `gh`, as you. Nothing is dispatched between repositories and no
|
|
192
190
|
credential is put on a public repo. The tracker issue goes first, because it is the half that
|
|
193
191
|
reaches anybody; if the copy on the pull request then fails you are told, rather than being
|
|
194
192
|
shown an error that invites you to ask the same person the same thing twice.
|
|
195
193
|
|
|
194
|
+
## Runs
|
|
195
|
+
|
|
196
|
+
What each staff member ran in the last 30 days: when, daily or mention, how it ended, how long
|
|
197
|
+
it took, turns and cost where known, and a link to the log. Above the tables, the 30-day total
|
|
198
|
+
for the org, and each staff member's own in their heading.
|
|
199
|
+
|
|
200
|
+
Runs are not in any repo, so this is the one screen that is only ever on GitHub. It reads the
|
|
201
|
+
run lists through your own `gh`, the same way the inbox does, and offline it says so rather
|
|
202
|
+
than drawing an empty table that reads as "nothing ran".
|
|
203
|
+
|
|
204
|
+
Cost comes from the record each run leaves behind (see [cost](cost.md#what-each-run-cost)). A
|
|
205
|
+
run from before records existed, or from an agent that does not report cost, shows a dash, and
|
|
206
|
+
a total says how many runs it could price. Each record is downloaded once and kept for as long
|
|
207
|
+
as the portal runs, so the first visit is the slow one.
|
|
208
|
+
|
|
209
|
+
A skipped mention is not a run and is not listed. A `setup-failure` is a run that failed before
|
|
210
|
+
the agent started, usually a token or a checkout. Past a [`budget`](org-yaml.md#budget), the
|
|
211
|
+
total turns amber.
|
|
212
|
+
|
|
196
213
|
## Org
|
|
197
214
|
|
|
198
215
|
The layer every staff member inherits, in one place: `org.yaml`, every `org/*.md`, and the
|
|
@@ -200,9 +217,8 @@ prompt files in `prompts/`, each with a line saying what it is for, because a fi
|
|
|
200
217
|
you nothing about which to open. Anything roster does not ship falls back to its own first
|
|
201
218
|
heading.
|
|
202
219
|
|
|
203
|
-
**The list comes off disk**, not out of the page
|
|
204
|
-
|
|
205
|
-
written `org/business.md` yet got "not found" with nothing to do about it. Only files the
|
|
220
|
+
**The list comes off disk**, not out of the page, so a tenant that adds `org/pricing.md` can
|
|
221
|
+
open it like any other. Only files the
|
|
206
222
|
portal may actually write are listed: an editor that offers a file it cannot save is a trap.
|
|
207
223
|
|
|
208
224
|
Every one of them is editable from the screen it is read on: an **Edit** button on the file,
|
|
@@ -225,18 +241,20 @@ have more than one human, and a card that names one of two reads as the only one
|
|
|
225
241
|
|
|
226
242
|
## Staff
|
|
227
243
|
|
|
228
|
-
Everyone on the roster, and the
|
|
244
|
+
Everyone on the roster, and the things you would otherwise do from a terminal.
|
|
229
245
|
|
|
230
246
|
**Hiring** runs the same `buildPlan` and `applyPlan` that `roster hire` does, on the server.
|
|
231
247
|
Only the handle is required; everything else is copied from whoever is already here. You see
|
|
232
|
-
the plan first, listing every file, every label, the schedule it chose and why,
|
|
233
|
-
|
|
234
|
-
|
|
248
|
+
the plan first, listing every file, every label, the schedule it chose and why, the commits it
|
|
249
|
+
will make as you in repos that already exist (each peer's `staff.yaml`, `org.yaml`), whether the
|
|
250
|
+
new brain joins the credential's org secret, and what is left for you. Nothing happens until you
|
|
251
|
+
apply. What the terminal would have printed is shown when it finishes.
|
|
235
252
|
|
|
236
253
|
**Writing the charter** is the copy-a-prompt loop below, aimed at `CHARTER.md`. `hire`
|
|
237
254
|
deliberately does not write it, because a generated charter produces exactly the generic agent
|
|
238
|
-
this whole arrangement exists to avoid.
|
|
239
|
-
|
|
255
|
+
this whole arrangement exists to avoid. It is the same brief as `roster brief charter
|
|
256
|
+
<handle>`, with somewhere to put the answer, and a picker for the worked example it carries as a
|
|
257
|
+
model: matched to the role, or another, or none.
|
|
240
258
|
|
|
241
259
|
**The GitHub App** is `roster app`, on this server rather than a second one. There is no API that
|
|
242
260
|
creates an App: the only route is the manifest flow, where you post a manifest to a settings page,
|
|
@@ -246,9 +264,17 @@ one origin. The private key is still held in memory and written straight to a re
|
|
|
246
264
|
|
|
247
265
|
GitHub redirects the tab *it* opened, not the one you clicked from, so the original polls for the
|
|
248
266
|
result. What it cannot do is install the App: that is a grant of access to specific repositories
|
|
249
|
-
and GitHub asks a
|
|
250
|
-
|
|
251
|
-
|
|
267
|
+
and GitHub asks a person to confirm it, which is correct and should not be worked around. So the
|
|
268
|
+
panel's **Install it** opens the install page with the org and the repos already selected: the
|
|
269
|
+
brain, every peer tracker it writes to, and the product repos. Any whose id could not be read are
|
|
270
|
+
listed for you to tick.
|
|
271
|
+
|
|
272
|
+
**Agent credential** is the setup screen's paste box, reachable from each card, because the
|
|
273
|
+
moment you look for it is while setting somebody up. It is once for the org.
|
|
274
|
+
|
|
275
|
+
**Run once now** starts the daily workflow, follows it, and shows how it ended with the log's
|
|
276
|
+
link and, on a failure, the step it failed at. It asks first, because it is a real run. A success
|
|
277
|
+
is what turns doctor's *unproven* into proven. Health has the same button.
|
|
252
278
|
|
|
253
279
|
**Retiring** is `roster retire`, and it is deliberately not deletion. A brain repo is that
|
|
254
280
|
agent's entire memory and there is no undo, so retiring disables the workflows, unwires them
|
|
@@ -284,8 +310,8 @@ rather than going nowhere.
|
|
|
284
310
|
|
|
285
311
|
## Prompt
|
|
286
312
|
|
|
287
|
-
**What this staff member is actually sent**,
|
|
288
|
-
|
|
313
|
+
**What this staff member is actually sent**, the same as `roster prompt <handle> --kind daily`.
|
|
314
|
+
Composed on the server by the tenant's own
|
|
289
315
|
`compose.mjs`, so there is no second implementation to drift.
|
|
290
316
|
|
|
291
317
|
Pick the kind: `daily` or `mention`. A mention prompt is written for the comment
|