Skip to content

feat(coordination): type ask_human questions and fail closed on automated answers - #719

Merged
unohee merged 2 commits into
mainfrom
feat/hermes-question-class
Sep 25, 2026
Merged

unohee merged 2 commits into
mainfrom
feat/hermes-question-class

Conversation

@unohee

@unohee unohee commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

What

ask_human gains a typed question class, and the answer side fails closed (AGT-4514).

  • Agents may mark a question clarification (informational — a fact the asker could not look up) or approval (credentials, spend, production access, an irreversible external action — a human must own it). Absent means approval.
  • The class an agent supplies is a claim, not proof. The gate that makes it load-bearing is in answerHumanQuestion: an automated responder may only answer a question that is exactly clarification.
  • Fails closed in the direction that denies automation. Anything not exactly clarification — absent, misspelled, or a stale enum value from an agent written before this field existed — resolves to approval, so every existing caller is refused automation rather than silently granted it.
  • Human surfaces are recognised by an allowlist of the actor itself, not by a caller-supplied role: the dashboard route, a discord: actor, and OpenSwarm's own supervisor (which answers with the authority the operator delegated). A connector that omits the role, or claims human, is still treated as automated.
  • A refused answer is left unsettled, so a human can still answer the question afterwards.
  • Question class is persisted in the posted event's metadata, so the gate can re-read it after the fact.

Why it is safe to merge

  • No change to resume/ledger behaviour: the diff touches only question posting/answering and the ask_human tool's input surface.
  • Every pre-existing human surface keeps working — covered by a test that answers an approval question from each allowlisted surface.
  • The default direction denies automation, so an un-updated agent loses capability it should not have had, not an ability it should have kept.

Verification

$ node --experimental-vm-modules node_modules/vitest/vitest.mjs run \
    src/coordination/humanQuestions.test.ts src/coordination/coordinationTools.test.ts
 Test Files  2 passed (2)
      Tests  48 passed (48)

$ npm run lint       # exit 0 (pre-existing warnings only)
$ npm run typecheck  # clean

Includes explicit fail-closed cases: no class ⇒ refused, omitted/human-claiming automated role ⇒ refused, clarification ⇒ allowed, refused answer remains answerable by a human.

Refs: AGT-4514

Heewon Oh and others added 2 commits September 24, 2026 17:58
…ated answers

Agents may now mark a question `clarification` (informational, answerable by an
automated responder) or `approval` (credentials, spend, production access or an
irreversible external action — a human must own it). The class an agent supplies
is a claim, not proof: the gate in `answerHumanQuestion` is what makes the
distinction load-bearing, and it fails closed.

Anything that is not exactly `clarification` — absent, misspelled or a stale enum
value from an older agent — resolves to `approval`, so every caller that predates
this field is refused automation. Human surfaces are recognised by an allowlist
(dashboard route, `discord:` actor, OpenSwarm's own supervisor), not by a
caller-supplied role, so a connector that omits the role or claims `human` is
still treated as automated. A refused answer is left unsettled, so a human can
still answer it.

Verified: src/coordination/humanQuestions.test.ts + coordinationTools.test.ts
48/48 pass, `npm run lint` exit 0, `npm run typecheck` clean.

Refs: AGT-4514
@unohee
unohee merged commit 5fdb27a into main Sep 25, 2026
7 checks passed
@unohee
unohee deleted the feat/hermes-question-class branch September 25, 2026 05: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