Skip to content

feat: verify AgentWorkforce persona spawns - #1464

Open
khaliqgant wants to merge 7 commits into
mainfrom
codex/issue-306-persona-spawn
Open

feat: verify AgentWorkforce persona spawns#1464
khaliqgant wants to merge 7 commits into
mainfrom
codex/issue-306-persona-spawn

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Aug 7, 2026

Copy link
Copy Markdown
Member

Summary

  • let the Agent Relay spawn MCP tool accept an AgentWorkforce persona id or JSON path instead of a raw CLI and wait for the terminal capability result
  • keep plain spawn:persona actions on their dynamically resolved CLI rather than rewriting them as native persona harness shadows, with a runtime feature marker for dependent SDKs
  • hold verified broker spawn results until strict node registration plus worker_ready, with duplicate-name rejection, a 90-second deadline, and release/deregistration on failure
  • expose replay-safe SpawnedAgentHandle.waitForReady() and document the AgentWorkforce fleet-node path

This is the Relay part of AgentWorkforce/workforce#306. It uses the in-process Fleet/SDK path and does not invoke the agentworkforce binary.

Verification

  • cargo test -p agent-relay-broker --lib — 860 passed, 4 ignored
  • focused Fleet, harness-driver, and MCP tests — 53 passed
  • harness-driver build — exit 0
  • Fleet build — exit 0
  • CLI TypeScript check — exit 0
  • cargo fmt --all and cargo check -p agent-relay-broker — exit 0

Stack

Publish this as Agent Relay 11.5+ before the dependent Workforce local-surface PR is released.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The MCP spawn tool now accepts AgentWorkforce personas. Persona spawns use spawn:persona, require registration, and wait for broker and harness readiness. The broker tracks verified spawns through completion and failure states.

Changes

Persona spawning and readiness

Layer / File(s) Summary
Readiness event contract
packages/harness-driver/src/agent-handle.ts, packages/harness-driver/src/agent-result.test.ts, packages/harness-driver/src/client.ts
SpawnedAgentHandle.waitForReady() reports readiness, exit, and timeout outcomes. Event handling uses the current agent generation.
Broker verified-spawn lifecycle
crates/broker/src/protocol.rs, crates/broker/src/runtime/event_loop.rs, crates/broker/src/runtime/fleet.rs, crates/broker/src/runtime/init.rs, crates/broker/src/runtime/maintenance.rs, crates/broker/src/runtime/relaycast_events.rs, crates/broker/src/runtime/worker_events.rs
The broker tracks verified spawns until worker_ready, enforces readiness timeouts, handles worker release and exit, and requires node registration when metadata requests it.
Fleet persona delegation
packages/fleet/src/index.ts, packages/fleet/src/serve-node.ts, packages/fleet/src/serve-node.test.ts, packages/fleet/README.md
Fleet delegation now applies to explicit spawn: capabilities. Persona node setup and delegation behavior are documented and tested.
MCP persona spawn flow
packages/cli/src/cli/agent-relay-mcp.ts, packages/cli/src/cli/agent-relay-mcp.startup.test.ts, CHANGELOG.md
The MCP tool enforces CLI/persona exclusivity, invokes persona spawns through messaging, polls invocation status, and returns after readiness completes. Tests cover the completed response.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant Messaging
  participant Broker
  participant Worker
  MCPClient->>Messaging: invoke spawn:persona
  Messaging->>Broker: create verified spawn
  Broker->>Worker: start persona worker
  Worker->>Broker: report registration and worker_ready
  Broker-->>Messaging: return completed invocation
  Messaging-->>MCPClient: return readiness result
Loading

Possibly related issues

  • AgentWorkforce/workforce issue 306 — Covers persona-based Agent Relay spawning and broker/harness readiness verification.
  • AgentWorkforce/relay issue 1430 — Covers awaiting worker readiness before reporting spawn success.

Possibly related PRs

Suggested reviewers: willwashburn, claude

Poem

A rabbit sends a persona call,
The broker tracks the worker’s start.
Registration opens the way,
Readiness ends the pending state.
Timeout and exit paths report,
The MCP result returns complete.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: verification of AgentWorkforce persona spawns.
Description check ✅ Passed The description explains the changes, verification results, scope, and release dependency; it omits the template's explicit Test Plan and Screenshots headings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-306-persona-spawn

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@khaliqgant
khaliqgant marked this pull request as ready for review August 8, 2026 11:12
@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@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: 8696810e9f

ℹ️ 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 thread crates/broker/src/runtime/maintenance.rs
Comment thread packages/harness-driver/src/agent-handle.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/cli/src/cli/agent-relay-mcp.ts (1)

771-807: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Split the spawn execution branches.

The async handler has complexity 22. The configured limit is 15. Extract the raw CLI path and persona path into dedicated helpers. Keep validation and action-input construction in small helpers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/cli/agent-relay-mcp.ts` around lines 771 - 807, Reduce the
complexity of the spawn handler by extracting the non-persona CLI invocation and
persona invocation into dedicated helper functions. Keep the existing validation
checks in the handler, and move actionInput construction into a small helper so
the handler only validates inputs, builds the request, and dispatches through
the appropriate helper while preserving current behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/broker/src/runtime/fleet.rs`:
- Around line 533-542: Update crates/broker/src/runtime/fleet.rs lines 533-542
so the deregistration result from deregister_fleet_agent is handled: only prune
local Fleet state after AgentDeregister is successfully queued, while
channel-full or closed errors retain the FleetDeliveryBook entry and schedule
retryable cleanup. Apply the same flow in
crates/broker/src/runtime/maintenance.rs lines 120-129 before removing timed-out
worker Fleet state; both sites must preserve state until deregistration
succeeds.

In `@packages/cli/src/cli/agent-relay-mcp.ts`:
- Around line 83-107: Update waitForPersonaSpawn to catch failures from
actions.getInvocation and retry transient network or authorization read errors
until deadline, preserving the existing polling interval. Fail immediately for
confirmed terminal invocation failures and non-retryable errors such as
invalid-agent-token responses, while retaining the current timeout and success
handling.

---

Nitpick comments:
In `@packages/cli/src/cli/agent-relay-mcp.ts`:
- Around line 771-807: Reduce the complexity of the spawn handler by extracting
the non-persona CLI invocation and persona invocation into dedicated helper
functions. Keep the existing validation checks in the handler, and move
actionInput construction into a small helper so the handler only validates
inputs, builds the request, and dispatches through the appropriate helper while
preserving current behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ba52309-4515-4d5c-89aa-c11c1931f570

📥 Commits

Reviewing files that changed from the base of the PR and between 7a42f3b and 8696810.

📒 Files selected for processing (16)
  • CHANGELOG.md
  • crates/broker/src/protocol.rs
  • crates/broker/src/runtime/event_loop.rs
  • crates/broker/src/runtime/fleet.rs
  • crates/broker/src/runtime/init.rs
  • crates/broker/src/runtime/maintenance.rs
  • crates/broker/src/runtime/relaycast_events.rs
  • crates/broker/src/runtime/worker_events.rs
  • packages/cli/src/cli/agent-relay-mcp.startup.test.ts
  • packages/cli/src/cli/agent-relay-mcp.ts
  • packages/fleet/README.md
  • packages/fleet/src/index.ts
  • packages/fleet/src/serve-node.test.ts
  • packages/fleet/src/serve-node.ts
  • packages/harness-driver/src/agent-handle.ts
  • packages/harness-driver/src/agent-result.test.ts

Comment thread crates/broker/src/runtime/fleet.rs Outdated
Comment thread packages/cli/src/cli/agent-relay-mcp.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 16 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/broker/src/runtime/worker_events.rs Outdated
Comment thread crates/broker/src/runtime/fleet.rs Outdated
Comment thread packages/harness-driver/src/agent-handle.ts Outdated
Comment thread crates/broker/src/runtime/relaycast_events.rs Outdated
Comment thread crates/broker/src/runtime/maintenance.rs
Comment thread crates/broker/src/runtime/maintenance.rs Outdated
Comment thread packages/cli/src/cli/agent-relay-mcp.startup.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/harness-driver/src/agent-handle.ts`:
- Line 75: Scope SpawnedAgentHandle event lookups to the current spawn
generation instead of relying only on the reused agent name or the Date.now()
readyNotBefore boundary. Update the handle’s event-tracking state and the logic
around waitForReady/exit (including the queryEvents usage at lines 146-148) to
establish a reliable per-spawn boundary, such as the relevant worker_ready event
or broker-provided handle ID, so in-flight events are found and prior workers’
worker_ready/agent_exited events cannot satisfy the current handle.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 024722d2-17b5-4dd0-9601-ec602c035898

📥 Commits

Reviewing files that changed from the base of the PR and between 8696810 and 8344882.

📒 Files selected for processing (7)
  • crates/broker/src/runtime/fleet.rs
  • crates/broker/src/runtime/maintenance.rs
  • crates/broker/src/runtime/relaycast_events.rs
  • crates/broker/src/runtime/worker_events.rs
  • packages/cli/src/cli/agent-relay-mcp.startup.test.ts
  • packages/cli/src/cli/agent-relay-mcp.ts
  • packages/harness-driver/src/agent-handle.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/cli/src/cli/agent-relay-mcp.startup.test.ts
  • crates/broker/src/runtime/maintenance.rs
  • packages/cli/src/cli/agent-relay-mcp.ts
  • crates/broker/src/runtime/worker_events.rs
  • crates/broker/src/runtime/relaycast_events.rs
  • crates/broker/src/runtime/fleet.rs

Comment thread packages/harness-driver/src/agent-handle.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/harness-driver/src/agent-handle.ts Outdated
Comment thread crates/broker/src/runtime/maintenance.rs
Comment thread crates/broker/src/runtime/fleet.rs Outdated
Comment thread crates/broker/src/runtime/worker_events.rs Outdated
Comment thread packages/harness-driver/src/agent-handle.ts Outdated
Comment thread packages/cli/src/cli/agent-relay-mcp.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread crates/broker/src/runtime/worker_events.rs Outdated
Comment thread packages/harness-driver/src/agent-handle.ts Outdated
Comment thread packages/cli/src/cli/agent-relay-mcp.ts Outdated
Comment thread crates/broker/src/runtime/relaycast_events.rs
Comment thread packages/cli/src/cli/agent-relay-mcp.startup.test.ts
Comment thread crates/broker/src/runtime/maintenance.rs
Comment thread packages/harness-driver/src/agent-handle.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/broker/src/runtime/fleet.rs (1)

626-632: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the pending spawn only after a successful release.

If release_worker_locally() returns ReleaseOutcome::Failed, this code removes the verified spawn and sends spawn_released_before_ready. A later valid worker_ready cannot complete the original spawn action. Move this block into the ReleaseOutcome::Released path.

Proposed fix
-        if let Some(pending) = self.pending_verified_spawns.remove(&name) {
-            self.send_fleet_action_result(verified_spawn_failed_result(
-                pending.invocation_id,
-                "spawn_released_before_ready",
-            ))
-            .await;
+        if outcome == super::relaycast_events::ReleaseOutcome::Released {
+            if let Some(pending) = self.pending_verified_spawns.remove(&name) {
+                self.send_fleet_action_result(verified_spawn_failed_result(
+                    pending.invocation_id,
+                    "spawn_released_before_ready",
+                ))
+                .await;
+            }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/broker/src/runtime/fleet.rs` around lines 626 - 632, Move the
pending_verified_spawns removal and verified_spawn_failed_result notification
out of the unconditional release handling and into the ReleaseOutcome::Released
branch of release_worker_locally(). Preserve the pending spawn and avoid sending
spawn_released_before_ready when the release outcome is ReleaseOutcome::Failed,
so a later worker_ready can complete the original action.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/broker/src/runtime/worker_events.rs`:
- Around line 751-759: Bind lifecycle handling to an immutable broker-assigned
worker generation: in crates/broker/src/runtime/worker_events.rs:751-759, store
the expected generation in PendingVerifiedSpawn and complete only matching
worker_ready events; in packages/harness-driver/src/client.ts:581-588 and
:624-631, obtain that generation atomically for PTY, CLI, and headless spawns
and pass it through; in packages/harness-driver/src/agent-handle.ts:276-286,
filter history and live lifecycle events by generation rather than name and
temporal cutoff. Add a regression test covering an old worker event arriving
between release and same-name respawn completion.

---

Outside diff comments:
In `@crates/broker/src/runtime/fleet.rs`:
- Around line 626-632: Move the pending_verified_spawns removal and
verified_spawn_failed_result notification out of the unconditional release
handling and into the ReleaseOutcome::Released branch of
release_worker_locally(). Preserve the pending spawn and avoid sending
spawn_released_before_ready when the release outcome is ReleaseOutcome::Failed,
so a later worker_ready can complete the original action.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9eb5f52b-d809-41a2-90bd-a3d3e6959015

📥 Commits

Reviewing files that changed from the base of the PR and between 8344882 and bbb70df.

📒 Files selected for processing (9)
  • crates/broker/src/runtime/fleet.rs
  • crates/broker/src/runtime/maintenance.rs
  • crates/broker/src/runtime/relaycast_events.rs
  • crates/broker/src/runtime/worker_events.rs
  • packages/cli/src/cli/agent-relay-mcp.startup.test.ts
  • packages/cli/src/cli/agent-relay-mcp.ts
  • packages/harness-driver/src/agent-handle.ts
  • packages/harness-driver/src/agent-result.test.ts
  • packages/harness-driver/src/client.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/cli/src/cli/agent-relay-mcp.startup.test.ts
  • crates/broker/src/runtime/relaycast_events.rs
  • crates/broker/src/runtime/maintenance.rs
  • packages/harness-driver/src/agent-result.test.ts
  • packages/cli/src/cli/agent-relay-mcp.ts

Comment on lines +751 to +759
if let Some(pending) = pending_verified_spawns.remove(&name) {
let _ = fleet_control_tx
.send(FleetControlCommand::Send(
crate::fleet_wire::BrokerToRelaycast::ActionResult(
verified_spawn_ready_result(pending.invocation_id, &name),
),
))
.await;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Bind lifecycle events to an immutable spawn generation.

A cursor captured before /api/spawn excludes only events that already exist. It accepts an old same-name event emitted after the cursor read and before the new spawn is established. The broker also completes a verified spawn from any worker_ready with the same name. A release followed by a fast respawn can therefore mark the new action ready from an old worker event, or resolve the new handle from an old exit.

  • crates/broker/src/runtime/worker_events.rs#L751-L759: Store the expected worker generation in PendingVerifiedSpawn. Complete it only when the readiness event has that generation.
  • packages/harness-driver/src/client.ts#L581-L588: Obtain a broker-assigned generation identifier atomically with the PTY spawn result.
  • packages/harness-driver/src/client.ts#L624-L631: Obtain and pass the same identifier for CLI and headless spawns.
  • packages/harness-driver/src/agent-handle.ts#L276-L286: Filter lifecycle history and live events by that identifier instead of a name plus temporal cutoff.

Add a regression test that queues an old worker's lifecycle event after release and before a same-name respawn completes.

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 5 \
  'enum WorkerEvent|struct WorkerEvent|WorkerEvent::Message|spawn_worker_from_request|release_worker_locally|pending_verified_spawns|worker_ready' \
  crates/broker/src packages/harness-driver/src
📍 Affects 3 files
  • crates/broker/src/runtime/worker_events.rs#L751-L759 (this comment)
  • packages/harness-driver/src/client.ts#L581-L588
  • packages/harness-driver/src/client.ts#L624-L631
  • packages/harness-driver/src/agent-handle.ts#L276-L286
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/broker/src/runtime/worker_events.rs` around lines 751 - 759, Bind
lifecycle handling to an immutable broker-assigned worker generation: in
crates/broker/src/runtime/worker_events.rs:751-759, store the expected
generation in PendingVerifiedSpawn and complete only matching worker_ready
events; in packages/harness-driver/src/client.ts:581-588 and :624-631, obtain
that generation atomically for PTY, CLI, and headless spawns and pass it
through; in packages/harness-driver/src/agent-handle.ts:276-286, filter history
and live lifecycle events by generation rather than name and temporal cutoff.
Add a regression test covering an old worker event arriving between release and
same-name respawn completion.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 9 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/broker/src/runtime/fleet.rs">

<violation number="1" location="crates/broker/src/runtime/fleet.rs:615">
P1: Fleet control receives `released: true` when `agent.deregister` could not be queued, so it has no reason to retry and the retained authoritative identity can remain registered indefinitely. Preserve the identity as here, but return an action error when deregistration enqueue fails.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

)
.await;
}
Err(error) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1: Fleet control receives released: true when agent.deregister could not be queued, so it has no reason to retry and the retained authoritative identity can remain registered indefinitely. Preserve the identity as here, but return an action error when deregistration enqueue fails.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/broker/src/runtime/fleet.rs, line 615:

<comment>Fleet control receives `released: true` when `agent.deregister` could not be queued, so it has no reason to retry and the retained authoritative identity can remain registered indefinitely. Preserve the identity as here, but return an action error when deregistration enqueue fails.</comment>

<file context>
@@ -595,13 +595,34 @@ impl BrokerRuntime {
+                    )
+                    .await;
+                }
+                Err(error) => {
+                    tracing::warn!(worker = %name, %error, "retaining fleet identity after release cleanup");
+                    prune_fleet_inventory_entry(
</file context>

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.

2 participants