You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Record who approved each seat on the roster snapshot #234
crews.md AC6 and AC20 and agent-tools.md line 220 say the roster snapshot records who approved each seat and why. The store never has: j5_agent_crew_member (apps/server/src/j5/a2a/migrations/014_AgentCrews.ts:44-55) carries reason and added_version only, and the migration's header records that the earlier approved_by column was removed on purpose because it existed only for runbooks. Human-added seats get the reason "Added by the user" (apps/web/src/j5/crew/crewProposalDraft.ts:36), and the retired roster on the Fleet page shows seat, persona, version, and reason, never an approver.
Blocked on my decision, which I will record on this issue: with one local operator today, is "who approved" always the person and therefore redundant, in which case the doc sentences narrow (fold that into #229 and close this one), or should the field come back ahead of multi-person environments?
What should change if the field comes back:
A new J5 migration adds a nullable approver column (the approving person's participant id) to j5_agent_crew_member. Old rows stay null; do not invent values.
Set it from the authenticated resolving route through CrewProposalService.resolve, CrewLaunchService.launch and addSeats, and AgentCrewInstanceService.record and addMembers.
Carry it through FleetCrew.roster in packages/contracts/src/j5.ts and FleetReadsHttp.ts, and render it on the retired Crew item in FleetPage.tsx beside the reason.
Tests beside each touched module, plus a Migrations.test.ts case for the upgrade.
Done when the retired roster on the Fleet page shows who approved each seat for every Crew launched after the migration, or when the docs no longer promise it.
Related criteria: crews.md AC6, AC20.
Dependencies: blocked on the decision below. If the field comes back, land after #228 to avoid two PRs editing the retired Crew item on the Fleet page at once.
Edit (2026-09-24, after the upstream sync in #256 and the Fleet rework in #241/#242)
The decision still stands. These references and requirements changed:
Doc and code locations. The approver promise is at agent-tools.md line 215, crews.md line 56 (AC6), and line 82 (AC20). The human-added reason is crewProposalDraft.ts:33. FleetCrew in packages/contracts/src/j5.ts contradicts itself: the struct doc says "who approved each seat and why", while the roster comment says "Every seat was approved by the person".
There is no approver identity on the route today.CrewProposalsHttp.ts resolves under authenticateOperate, which checks the session's operate scope and carries no person. The only J5 human is the host-local operator in HumanPersonRegistry.ts. So "the approving person's participant id" can only mean the host-local operator's person id, looked up on the server and never taken from the request body. Recording a real approver in a multi-person environment first needs a session-to-person binding, which is its own issue. This supports the "redundant" option.
Bring it back: add a new J5 migration with a nullable approver column on j5_agent_crew_member; old rows stay null. The server sets it to the host-local operator's person id inside CrewProposalService.resolve, then carries it through CrewLaunchService.launch / addSeats, AgentCrewInstanceService.record / addMembers, FleetCrew.roster, and FleetReadsHttp.ts. Render it in RetiredCrewItem next to the reason. Ship tests beside each touched module plus a Migrations.test.ts upgrade case. If this lands with Crew groups and Fleet rows keep seats without thread facts as unknown #227, sequence it after Crew groups and Fleet rows keep seats without thread facts as unknown #227, since both edit the J5 Fleet contract.
The question: with one local operator today, is "who approved" always the person and therefore redundant, or should the approver field come back ahead of multi-person environments?
Bring it back: a new J5 migration adds a nullable approver column, set from the authenticated resolving route, carried through the J5 Fleet contract and rendered on the retired Crew item. Old rows stay null.
My lean is redundant for now, since the column was removed on purpose on 2026-09-15 and nothing reads it. Reply here with your pick and I will update the issue.
My call: the approver field is redundant. With one host-local operator, the person approves every seat, and nothing on the route identifies anyone else. I'm narrowing AC6, AC20, agent-tools.md line 215, and the FleetCrew struct comment to say the person approves every seat, and that work moves into #229. If multi-person environments come, recording a real approver starts with binding sessions to people, which gets its own issue.
crews.md AC6 and AC20 and
say the roster snapshot records who approved each seat and why. The store never has:agent-tools.mdline 220j5_agent_crew_member(apps/server/src/j5/a2a/migrations/014_AgentCrews.ts:44-55) carriesreasonandadded_versiononly, and the migration's header records that the earlierapproved_bycolumn was removed on purpose because it existed only for runbooks. Human-added seats get the reason "Added by the user"(, and the retired roster on the Fleet page shows seat, persona, version, and reason, never an approver.apps/web/src/j5/crew/crewProposalDraft.ts:36)Blocked on my decision, which I will record on this issue: with one local operator today, is "who approved" always the person and therefore redundant, in which case the doc sentences narrow (fold that into #229 and close this one), or should the field come back ahead of multi-person environments?
What should change if the field comes back:
j5_agent_crew_member. Old rows stay null; do not invent values.Set it from the authenticated resolving route through,CrewProposalService.resolveCrewLaunchService.launchandaddSeats, andAgentCrewInstanceService.recordandaddMembers.FleetCrew.rosterinpackages/contracts/src/j5.tsandFleetReadsHttp.ts,and render it on the retired Crew item inFleetPage.tsxbeside the reason.Migrations.test.tscase for the upgrade.Done when the retired roster on the Fleet page shows who approved each seat for every Crew launched after the migration, or when the docs no longer promise it.
Related criteria: crews.md AC6, AC20.
Dependencies: blocked on the decision below.
If the field comes back, land after #228 to avoid two PRs editing the retired Crew item on the Fleet page at once.Edit (2026-09-24, after the upstream sync in #256 and the Fleet rework in #241/#242)
The decision still stands. These references and requirements changed:
agent-tools.mdline 215, crews.md line 56 (AC6), and line 82 (AC20). The human-added reason iscrewProposalDraft.ts:33.FleetCrewinpackages/contracts/src/j5.tscontradicts itself: the struct doc says "who approved each seat and why", while therostercomment says "Every seat was approved by the person".CrewProposalsHttp.tsresolves underauthenticateOperate, which checks the session's operate scope and carries no person. The only J5 human is the host-local operator inHumanPersonRegistry.ts. So "the approving person's participant id" can only mean the host-local operator's person id, looked up on the server and never taken from the request body. Recording a real approver in a multi-person environment first needs a session-to-person binding, which is its own issue. This supports the "redundant" option.RetiredCrewIteminFleetPage.tsx, a one-line<details>row in the cross-Squadron Retired section. Each roster line reads "approved at vN · reason".whitespace-pre-wrap, noline-clamp) when the row is expanded, so The retired Crew brief can be read in full on the Fleet page #228 looks satisfied already and the ordering constraint no longer applies. If The retired Crew brief can be read in full on the Fleet page #228 is closed, drop the dependency.Revised steps:
agent-tools.mdline 215 to say the person approves every seat. Fix theFleetCrewstruct comment to match. Close this issue. Leave the worklog history as written.j5_agent_crew_member; old rows stay null. The server sets it to the host-local operator's person id insideCrewProposalService.resolve, then carries it throughCrewLaunchService.launch/addSeats,AgentCrewInstanceService.record/addMembers,FleetCrew.roster, andFleetReadsHttp.ts. Render it inRetiredCrewItemnext to the reason. Ship tests beside each touched module plus aMigrations.test.tsupgrade case. If this lands with Crew groups and Fleet rows keep seats without thread facts as unknown #227, sequence it after Crew groups and Fleet rows keep seats without thread facts as unknown #227, since both edit the J5 Fleet contract.