Skip to content

feat(cli): add result metadata fd transport - #18

Closed
cermm wants to merge 1 commit into
mainfrom
issue-358-result-meta-fd-18b50851f0
Closed

feat(cli): add result metadata fd transport#18
cermm wants to merge 1 commit into
mainfrom
issue-358-result-meta-fd-18b50851f0

Conversation

@cermm

@cermm cermm commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the NousResearch#358/NousResearch#401 producer-bound --result-meta-fd transport on current cermm/hermes-agent main.

  • Adds closed-world hermes-agent-result-meta-v1 frame generation.
  • Preserves legacy process exit behavior when the flag is absent.
  • With a valid result-metadata FD, a zero process exit means the frame was published; semantic failure/interruption remains in the frame.
  • Publishes bounded interrupted and unknown_failure frames for quiet KeyboardInterrupt / unexpected exceptions without raw exception/path/secret leakage.
  • Rejects duplicate --result-meta-fd options before descriptor claim/startup and keeps the standalone parser aligned.

Exact gate evidence

Base/fork main before candidate: e0c3e1b098e719d2f7327b202755ace76414212f.
Candidate commit: 18b50851f037c4686bd6be77aff092098973c899.
Candidate tree: bb1e4c3ada50641c5ecbf0a7260018f4bb76db5f.
Reviewed Kanban gates: t_f74bbba6 repair handoff, t_2a4921d3 independent GPT-5.6 PASS (PASS_REVIEW_RESULT_META_FD_DUPLICATE_REPAIR).

Local verification rerun from /home/michal/worktrees/nousresearch-hermes-agent/issue358-result-meta-current-main-20260816:

  • scripts/run_tests.sh tests/hermes_cli/test_result_metadata.py tests/hermes_cli/test_result_metadata_cli.py -q → 44 passed, 0 failed.
  • 12-file affected CLI suite (test_result_metadata*, parser/flags/startup/safe-mode/relaunch/coalesce/container/yolo/subparser) → 209 passed, 0 failed.
  • /home/michal/.hermes/hermes-agent/venv/bin/python -m ruff check cli.py hermes_cli/_parser.py hermes_cli/main.py hermes_cli/result_metadata.py tests/hermes_cli/test_result_metadata.py tests/hermes_cli/test_result_metadata_cli.py → All checks passed.
  • python -m compileall -q on six Python scope files → exit 0.
  • python -m hermes_cli.main chat --help exposes --result-meta-fd.
  • git diff --check → exit 0.

Boundaries

This is repository code/docs/tests only. It does not mutate live Hermes profiles, SOUL files, auth stores, runtime config, canary state, rollout state, or wc-infrastructure issue closure.

Refs cermm/wc-infrastructure#358
Refs cermm/wc-infrastructure#401

Refs cermm/wc-infrastructure#358

Refs cermm/wc-infrastructure#401

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18b50851f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +125 to +129
if descriptor_target is None:
raise ResultMetadataError(
"result metadata descriptor identity is unavailable"
)
if not descriptor_target.startswith("pipe:"):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept valid pipes on non-Linux POSIX hosts

On macOS and other POSIX hosts without Linux procfs, /proc/self/fd is unavailable and /dev/fd/<n> is not guaranteed to be a symlink whose target begins with pipe:. Consequently, a valid anonymous pipe that already passes fstat, access-mode, blocking, and PC_PIPE_BUF validation is rejected as having unavailable or invalid identity, despite the option being documented for POSIX generally. The fallback test only mocks /proc failure while retaining Linux /dev/fd behavior, so this needs validation on the actual supported host path.

AGENTS.md reference: AGENTS.md:L84-L87

Useful? React with 👍 / 👎.

Comment thread cli.py
Comment on lines +12594 to +12595
if getattr(self, "result_meta_fd", None) is not None:
self._publish_result_metadata(result)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Publish a frame for every accepted single query

This publication point is skipped whenever chat() returns before reaching the agent result, including _ensure_runtime_credentials() or _init_agent() returning false; the quiet path has the same omission when credential or agent initialization fails. The ownership guards then close the accepted descriptor without writing JSON, and the nonquiet path can even return success with an empty pipe, breaking callers that rely on the advertised one-frame contract. Unexpected exceptions in the nonquiet caller are likewise not converted because that caller catches only KeyboardInterrupt; centralize a bounded failure-frame fallback across both query paths.

AGENTS.md reference: AGENTS.md:L54-L57

Useful? React with 👍 / 👎.

Comment on lines +183 to +187
if type(max_iterations) is not int or max_iterations < 0:
max_iterations = 90
upper_bound = min(max_iterations + 1, MAX_API_CALLS)
value = result.get("api_calls")
if "api_calls" in result and type(value) is int and 0 <= value <= upper_bound:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound API calls by the configured turn limit

With the normal max_turns=90, successful turns may legitimately report 33–91 API calls, but this fixed cap rejects every count above 32, replaces it with zero, and changes failure_class from none to unknown_failure even when completed is true. This corrupts the metadata precisely for longer tool-driven runs; the accepted bound should remain related to max_iterations + 1 rather than freezing an unrelated enumeration limit.

AGENTS.md reference: AGENTS.md:L80-L83

Useful? React with 👍 / 👎.

@cermm

cermm commented Aug 16, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #19: same tree bb1e4c3ada50641c5ecbf0a7260018f4bb76db5f with contributor attribution repaired after the check-attribution gate rejected hermes-agent@local. Keeping #18 unmerged.

@cermm

cermm commented Aug 16, 2026

Copy link
Copy Markdown
Owner Author

Closing superseded PR; #19 carries the same reviewed result-metadata FD tree with accepted contributor attribution.

@cermm cermm closed this Aug 16, 2026
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