Files

11 KiB

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 <prd.approve decision id>.

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/<its Gitea user>/<branch>. 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.