Skip to content

feat(worker): secondmate role plumbing, child bounds, and release gate (R2/R3 PR 1) - #262

Merged
ruby-dlee merged 2 commits into
mainfrom
feat/secondmate-role-plumbing
Aug 19, 2026
Merged

feat(worker): secondmate role plumbing, child bounds, and release gate (R2/R3 PR 1)#262
ruby-dlee merged 2 commits into
mainfrom
feat/secondmate-role-plumbing

Conversation

@ruby-dlee

Copy link
Copy Markdown
Owner

What

First PR of the judged R2/R3 design (R2R3-DESIGN.md in the owner's evidence folder): the blanket 'workers never run secondmates' refusal starts becoming an explicit bound on child compute. Controller-only and inert - no spawn lane routes to role=secondmate yet; ordinary author requests are byte-unchanged (golden-tested).

  • verify_request: role author|secondmate. Depth one by construction (a compartment is requested only by the primary, so a secondmate owns author crewmates only, never another secondmate or nested team). Secondmate-owned author requests must name their parent generation; parent fields refused anywhere else.
  • Child bounds in command_request under the single lock that inserts (the ensure_unique_bindings atomicity): FM_SECONDMATE_CHILD_MAX concurrent (default 4, max 8), FM_SECONDMATE_CHILD_TOTAL lifetime (default 16, max 32, counted on the parent worker record under the same hold), parent-liveness (children admit only while the parent's entry is assigned). FM_AZURE_SECONDMATE_MAX (default 2, max 4) caps concurrent compartments.
  • command_release refuses releasing a parent with active children, atomically under the lock (deliberately NOT in the authority tool, which reads controller state lock-free).
  • role rides the worker record and every minted action; expected_tags, the Azure provider's action_tags, and the test fixture all branch on it so a compartment VM carries agent-capacity one-home-scoped-secondmate + child-launcher absent instead of the one-task-crewmate posture. General-worker tags byte-identical.

Verification

19 units green; new unit secondmate_role_bounds drives the REAL wrapper against the fixture provider and pins every advertised refusal by its exact string: depth-1, missing parent, parent-fields-elsewhere, unassigned parent, compartment cap, fan-out cap (fifth child), lifetime total (with the freed-slot-still-refuses case), release-with-live-children (a full digest-exact proof that then succeeds once children quiesce), post-release parent-liveness, plus the author-item key-set golden.

Seven mutations, each red against the committed tree: depth-1 dropped; fan-out cap dropped; lifetime total dropped; parent-liveness dropped; release children gate dropped; compartment cap dropped; the expected_tags role branch dropped (caught by the exactness machinery refusing the compartment as assigned).

bin/fm-lint.sh and fm-behavior-shards.sh --check 8 clean.

…e (R2/R3 PR 1)

The R2/R3 correction begins here, per R2R3-DESIGN.md: the blanket 'workers
never run secondmates' refusal becomes an explicit bound on child compute,
landed controller-first and inert (no spawn lane routes to it yet).

- verify_request accepts role author|secondmate. Depth one by construction:
  a secondmate compartment is requested only by the primary, so a secondmate
  owns author crewmates and never another secondmate or nested team. A
  secondmate-owned author request must name its parent generation; parent
  fields are refused anywhere else.
- Child bounds live in command_request under the ONE lock that inserts, the
  same atomicity ensure_unique_bindings relies on: FM_SECONDMATE_CHILD_MAX
  (default 4, max 8) concurrent children, FM_SECONDMATE_CHILD_TOTAL (default
  16, max 32) lifetime children counted on the parent worker record, and
  parent-liveness (children admit only while the parent's entry is assigned).
  FM_AZURE_SECONDMATE_MAX (default 2, max 4) bounds concurrent compartments.
- command_release refuses, atomically under the lock with the whole queue in
  hand, releasing a parent with active children.
- The worker record and every minted action carry role; expected_tags and
  the Azure provider's action_tags branch on it, so a compartment VM carries
  agent-capacity one-home-scoped-secondmate and child-launcher absent instead
  of lying that it is a one-task crewmate. General-worker tags byte-unchanged.

Every bound is pinned with its exact refusal string in a new unit driving the
real wrapper against the fixture provider, plus an author-request golden
asserting no compartment field leaks into ordinary items.
…ondmate lane, pair the parent fields

The review caught a design defect both proposals and the judge missed: a
LOCAL secondmate home requests its own cloud crewmates today with
owner_kind=secondmate and NO parent (the documented docs/azure-workers.md
lane, minted verbatim by fm-spawn.sh from the home marker), and the blanket
parent requirement hard-refused that argv, including idempotent re-requests
of pre-upgrade entries. The parent pair now marks a COMPARTMENT child
specifically: present means compartment child (bounds armed), absent means
the existing local-secondmate lane, byte-unchanged and now pinned by an
idempotent re-request test. A lone half of the pair refuses for every caller
shape (the review's identity-poisoning bypass). enforce_child_bounds fails
closed on a missing or mismatched parent worker record instead of silently
skipping the lifetime bound. Three generation-dimension gaps get red-path
coverage: a released compartment holds its cap slot while releasing and
frees it at complete; a hand-planted cross-generation child does not block
this generation's release; a child re-request with a changed parent
generation refuses as a different identity. docs/azure-workers.md's request
sentence now names both roles. Also deflaked the concurrency barrier: FIFO
release only frees readers already blocked, so release is an existence poll.
@ruby-dlee
ruby-dlee merged commit 99d5ec1 into main Aug 19, 2026
13 checks passed
@ruby-dlee
ruby-dlee deleted the feat/secondmate-role-plumbing branch August 19, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant