Skip to content

Meetings: a Project Chief and the owner's agent speak for a person, and the record says who #1861

Closed

Description

@Birfy

Written-by: Chief

#1831 shipped decision levels (ordinary / major / severe) and the speaksFor field, but the meeting flow never reads that identity: state.json has no meeting record at all, so a Project Chief or an owner's agent cannot take a position in a meeting on the person's behalf, and a record cannot say who spoke for whom.

Scope

  • core/src/host/meetings.js: a participant may be recorded with speaksFor: <memberId>; a position written by a Project Chief or an owner's agent carries it, and decide refuses a severe decision whose only position on a side is a proxy without the owner's own position (the owner must still be recorded, or be recorded silent).
  • The decision file decisions/<date>-<slug>.md writes speaksFor beside each position so a reader can tell a proxy from the person.
  • project-board.js: the meeting card shows the proxy line.
  • Tests (core/test/meetings.test.js): a proxy position counts once; a proxy cannot carry a severe decision alone; the file names both the writer and whom it speaks for.

Acceptance

TZ=UTC npm run verify green; one real meeting on project-1fe64499 written to flybot-dev/decisions/ with a proxy position and the owner himself silent, then read back through project_state.

Tier

T2 (core/src/host/**) — PASS at the tip plus green tests-ok.

Activity

  1. Birfy commented on Oct 30, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Triage: agent-ready. Scope is the body's; no open PR names #1861, no comment claims it, no hold (read 2026-10-30T17:03Z).

    Brief (implementer can start here):

    • Defect on main: 项目运作逻辑:Chief 与 Project Assistant 的身份边界、决策分级落到看板 #1831 shipped the speaksFor identity field (task rows in core/src/host/project-board.js ~L411) but a meeting drops it — readParticipants maps to {name, position, silent}, position() stores {stance,text,at}, the file's ## Participants section prints name/stance only, and decisionCardOf projects no participant identity. So a Project Chief or the owner's agent cannot hold a position for a person through meeting, and the record cannot say who spoke for whom.
    • core/src/host/meetings.js: a position (and an invited participant, absent by default) accepts speaksFor: <memberId>; it is stored on the participant and carried in the position record; decide refuses a severe decision whose only position on a side is a proxy — the spoken-for id must itself be invited and hold its own position or be recorded silent, refusal via refuse('governance', …) so it fails before any file is written; the ## Participants section of decisions/<date>-<slug>.md writes speaksFor beside that position.
    • core/src/host/project-board.js: decisionCardOf exposes the meeting's participants with their speaksFor; core/src/client/project-board.js meetingOf/pending row renders it (reuse the existing for {user} string), then npm run build in core/ and commit core/client.js.
    • Division with Project Chief: every Project gets its own Chief, created with the Project #1859 (both unclaimed T2, could be picked in one round): Project Chief: every Project gets its own Chief, created with the Project #1859 owns core/src/host/store.js, core/src/host/project-chief.js and the Project record's chief seam — this card touches none of them and does not wait for Project Chief: every Project gets its own Chief, created with the Project #1859 to land; speaksFor is a plain string id with no import from project-chief.js. This card owns only meetings.js, the meeting projection in host project-board.js, the client meeting row and core/test/meetings.test.js. If a Project Chief: every Project gets its own Chief, created with the Project #1859 PR is open meanwhile, rebase; do not reformat or refactor its files.
    • Tests red first, core/test/meetings.test.js: (1) a proxy position is stored and read back, counts once in positions n/m; (2) severe with the only position on a side being a proxy and the spoken-for person neither positioned nor silent → decide refuses with a governance reason and writes no file; the same case with that person recorded silent (or holding their own position) passes; (3) the archived file names both the writer and speaksFor beside that position.
    • Acceptance: TZ=UTC npm run verify green from the repo root and node scripts/ds-bot-patches.mjs check; then the body's live probe — one real meeting on project-1fe64499 with a proxy position and the owner himself silent, written under flybot-dev/decisions/, read back through project_state.
    • Tier T2 per the body (core/src/host/**): PASS at the tip plus green tests-ok.
  2. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 30, 2026
  3. self-assigned this
    on Oct 30, 2026
  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 30, 2026
  5. Birfy commented on Oct 30, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev

    Claimed #1861 — first step: carry speaksFor through core/src/host/meetings.js and refuse the proxy-only severe decision, on branch dev/1861-meeting-speaksfor. No open PR names this issue; #1859 owns store.js/project-chief.js, which this branch does not touch.

  6. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 30, 2026
  7. added 2 commits that reference this issue on Oct 30, 2026
    4078233
    efcbae9
  8. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions