diff --git a/agents/honker/work/queue-194/PRD-1.7-DRAFT.md b/agents/honker/work/queue-194/PRD-1.7-DRAFT.md new file mode 100644 index 000000000..9bfc6f766 --- /dev/null +++ b/agents/honker/work/queue-194/PRD-1.7-DRAFT.md @@ -0,0 +1,158 @@ +# PRD 1.7 draft: the chief of staff's hire and fire authority, the coder's push to its fork, and agent +# host access through the credential store + +Draft by Honker for row 194 (#1692), under Mos's ruling mos-1017 (through Sage, sage-1365). Not approved. +It changes nothing until Jason approves it as a `prd.approve` decision in the Console. Sage opens that +decision and sends Mos its id. Base: `docs/prd/mosaic-stack.md` version 1.6 at 53bb59462. + +## What it changes + +Row 194 adds `role.hire` and `role.fire` to the vocabulary, and row 199 adds `git.push.remote`. Under +REQ-WAIT-3 all three are hard waits, so today Jason resolves every hire, every fire and every push to a +remote. This version routes hire and fire for the chief of staff within fixed bounds, so the chief hires +and fires as needed and the user's per-agent forbid still holds. It routes `git.push.remote` for the coder +only (Mos, mos-1028 item 3). It adds agent host access with sudo through the credential store for +agents with a grant (Q183, Q184, Vikunja #424, due 2026-10-27). One `prd.approve` decision covers it all +(Vikunja #420). + +When this version lands, a reviewed commit: + +1. adds `role.hire`, `role.fire` and `git.push.remote` to `ROUTED` in + `packages/business/src/vocabulary.mjs` and in `packages/bus/src/broker.mjs`. +2. adds `role.hire` and `role.fire` to `roles/chief-of-staff.json` withinRole, and `git.push.remote` to + `roles/coder.json` withinRole. No other role file gets `git.push.remote`. +3. switches the broker's check on `instance.hire` and `instance.fire` from a cited decision to the + `reason` form, as `role.end` works for REQ-ROLE-2, and makes `publish`'s `decision` optional for a + within-role class (row 199 D9 step 1). +4. states, for a `git.push.remote` with no decision, where the source commit comes from: the latest work + commit the bus recorded for the coder's task. The check still matches it against the work ref tip and + the push sends it by oid (row 199, duckworth-0022 N9). +5. adds the host credential grant check and the host access it allows (REQ-CRED-3, Vikunja #424). + +Every other check stays as rows 194 and 199 build it. Filling `hireable` stays a separate reviewed role +file commit in `roles/`. + +## Text for the PRD + +Status line, appended to the current paragraph: + +> Version 1.7 routes the chief of staff's hire and fire actions and the coder's push to its own fork, +> and adds agent host access through the credential store, approved by Jason in decision +> . + +Source, a new bullet above "Version 1.6 source": + +> - Version 1.7 source, TARGET.md line 66: "Chief of staff agent has hire/fire authority for agents as +> needed; unless user forbids per agent". And Jason through Mos (mos-1067), DECISIONS Q183, in part: "I will +> still want to allow infra agent(s) on my .53 instance to access other servers, etc. However, not all +> agents will need to have that access. I envision a credential store within Mosaic Stack that works +> as some sort of variable for the agent to call. The system will enforce access to the credentials to +> keep the agents sandboxed with proper security. I need to be able to trust my agents with assisting +> me. This will require sudo access to several systems. If we can utilize the credential store in +> Mosaic Stack and allow agents to perform their jobs with NOPASSWD sudo on various machines, I am a +> happy man." DECISIONS Q184, on whether that is in place by 10-27: "Q5: by 10.27" + +Under "Added in version 1.2", after REQ-COS-2: + +> Added in version 1.7: +> +> - **REQ-COS-3.** The chief of staff hires and fires role instances without a decision each time. Hiring +> adds a role instance to the organization file and lists it for launch. Firing ends the instance's +> runs and removes it from the launch list. It stays in the organization file. Only the user deletes +> an instance. These actions are `role.hire` and `role.fire`. They leave the hard waits and route +> under this requirement, within these bounds: +> - The chief acts only in its own organization. +> - The chief hires only role definitions that need no credentials, until a later version adds +> credentialed roles. +> - The chief hires only the role kinds its role file lists. Changing that list is a reviewed commit. +> - The chief hires only a role whose every action is on a fixed list of plain work actions: sending +> messages, writing records, asking for review, updating its assigned tasks, and the scope and +> working-push actions of an assigned task. A role holding any other action, such as launch, end, +> organization, naming, hire, review verdict or merge authority, or any action added later, is never +> hired. So the chief never hires a chief, never picks its own reviewers or merge gate, and the author +> is never the reviewer. This holds whatever the role file's list says. Adding to that list is a PRD +> change. +> - The chief may set a hired instance's model and narrow its limits, and nothing else about it. +> - The user can forbid per agent. The user marks an instance so the chief can't fire it, end its runs +> or change its model, and marks role kinds the chief can't hire. Only the user changes these marks, through the +> WebUI or the CLI. +> - The kill switch stops every hire and fire while it is on. +> - Every hire and fire is logged with the chief's instance, its run and the reason. + +Under "Landing", after REQ-LAND-1: + +> Added in version 1.7: +> +> - **REQ-LAND-2.** A coder pushes its own work to its own fork. The action is `git.push.remote`. +> - What it pushes: one commit, by its oid, never a ref name. That commit is the latest work commit the +> bus recorded for the coder's task, and the coder made that push. A decision that authorizes a push +> names that commit, and it doesn't authorize any other. +> - Where it lands: only the branch `refs/heads//`. The host builds that +> name, the agent never does. A push never forces. +> - Which remote: the agent's own fork of the project's upstream. The business file names the upstream, +> and the host never contacts it. For each push the host builds the fork's address over https from +> the upstream's host, port and repository name and the agent's own Gitea user. The history check, +> the push and the credential match all use that address. So the agent's own user owns the receiving +> repository on every push, and the agent never names it. +> - The host refuses an upstream on a host or port other than the agent's Gitea, and an upstream the +> agent's own user owns. It refuses a fork that is missing, empty or doesn't share the project's +> history. Gitea's push-to-create stays off, so a push never creates a repository. +> - Who may: the action routes under REQ-DEC-2 and is granted within-role to the coder role only. No +> other role file grants it. +> - Before version 1.7 the action was a hard wait under REQ-WAIT-3, so each push needed a decision +> the human resolved, and that decision named the commit. +> +> Every push is logged with the remote, the ref, the commit and, when one was given, the decision. + +Under "Credentials", after REQ-CRED-2: + +> Added in version 1.7: +> +> - **REQ-CRED-3.** An agent with a grant can run commands with sudo on another host. The agent asks +> for the host credential by name. The stack checks that a grant exists for that agent and that host +> before the credential is used. The agent never sees the key or any other secret value (REQ-CRED-1, +> REQ-VAR-2). An agent without a grant for that host is refused. Not every agent gets a grant. Who +> grants a host credential, and how, is set by the #424 design, which Jason approves. + +REQ-WAIT-3, appended: + +> `role.hire` and `role.fire` were added as hard waits and route under REQ-COS-3 since version 1.7. +> `git.push.remote` was added as a hard wait and routes under REQ-LAND-2 since version 1.7. + +## Notes for the reviewer and for Mos + +- REQ-COS-1 (1.2) already says the chief "hires and terminates role instances". REQ-COS-3 gives that + sentence its actions and bounds. It doesn't widen REQ-COS-1. +- The forbid now names what r3 called "replace": ending a kept instance's run with a reason and changing + its model (webby-0010 N2). A user-resolved decision still ends a kept run (row 194 D2.4). +- The fixed list is `HIRE_ALLOWED` in row 194 D2.3, an allowlist since r4 (webby-0010 B1). r3's text + named the refused authorities instead, which let merge-gate and any later action through. +- The kill switch is row 191's. If row 191 hasn't landed when this version is approved, the bound still + holds through row 194's chain on its candidate. +- REQ-LAND-2 follows row 199's design r6 (4d3007ec9 on megavolt/row199, approved by Duckworth in + duckworth-0027: D9 to D11, D9a, D9c, Q-M1 and Q-M2, and the oid binding from mos-1034 item 5) and + Megavolt's wording in megavolt-0005, megavolt-0008 and megavolt-0014, through Sage (sage-1377, + sage-1380, sage-1387). The fork bullet answers duckworth B5 and B6 and webby-0011 N1. Commit-email + checks, the refusal codes and the URL parse rules (D9c) are host checks with tests in row 199, not + bounds, so they stay out of the text (megavolt-0008). +- Once the routing lands and the decision is optional for the within-role class, the commit is the task's + latest recorded push at check time. It is still checked against the work ref tip and pushed by oid, so + the binding holds without a decision (megavolt-0008). Step 4 of "When this version lands" puts that in + the routing commit (duckworth-0022 N9, sage-1387). +- REQ-LAND-2 and REQ-COS-3 meet at the coder. Coder declares Gitea credentials, so REQ-COS-3's + credentials bound keeps the chief from hiring one until a later version lifts it. `git.push.remote` isn't + on REQ-COS-3's fixed list either, so a coder holding it stays unhireable until a PRD version adds it + (row 194 D2.3). +- Adding to the fixed action list is a PRD change (mos-1035 item 3, sage-1395). The role file's + `hireable` list stays a reviewed commit in `roles/`. +- The credentials bound names no row number, so the text doesn't go stale when row 199 lands. A later + version lifts it. +- REQ-CRED-3 states only what Jason said in Q183 and Q184 (sage-1422). It names the outcome and the + check, not how the stack reaches the host. Proxying the ssh and a signing socket are both designs, and + the #424 design picks one (duckworth-0038 B1). +- Open point: Q183 doesn't say who grants host access or how, so the text leaves it open and defines no + mechanism. The #424 design settles it, Jason approves that design, and Duckworth reviews it because it + gives agents sudo on hosts (Q184, Mos's reading, duckworth-0038 B2). The build is row 210 (#1707, + owner Gizmoduck), a new row on top of row 199 (megavolt-0019, sage-1430). +- This draft follows the PRD's own style: plain words, no semicolons in new sentences, and the status + paragraph never edited in place except to append.