Skip to content

feat: tool truncation + auto-compaction - #147

Merged
mikasenghaas merged 30 commits into
mainfrom
feat/context-compaction
Sep 1, 2026
Merged

feat: tool truncation + auto-compaction#147
mikasenghaas merged 30 commits into
mainfrom
feat/context-compaction

Conversation

@mikasenghaas

@mikasenghaas mikasenghaas commented Aug 26, 2026

Copy link
Copy Markdown
Member

Summary

  • make context compaction an explicit ExecutionPolicy.compaction option
  • use an explicit threshold or discover one from the model card with 16k tokens of headroom
  • compact after threshold crossings, context-bound decodes, and recognized provider overflows
  • retry checkpoints from the latest usage-verified conversation when the full checkpoint overflows
  • resample empty or tool-calling checkpoints and end cleanly when recovery is exhausted
  • apply the same policy to root agents and recursive agents while preserving IPython state
  • truncate tool results over 20KB before they enter the conversation
  • keep compaction prompts, context detection, and truncation helpers outside the main loop

Companion: verifiers #2454.

Breaking

  • ExecutionPolicy.compaction now controls proactive and reactive compaction.
  • ExecutionPolicy.summarize_at_tokens now defaults to None instead of 256_000.
  • Set compaction=true to enable compaction. Leave summarize_at_tokens unset to use model-card discovery.

Verification

  • uv run ruff check .
  • uv run ruff format --check .
  • UV_PROJECT_ENVIRONMENT=/tmp/nano-rlm-merge-tests.xApDnC/.venv uv sync --group dev
  • UV_PROJECT_ENVIRONMENT=/tmp/nano-rlm-merge-tests.xApDnC/.venv uv run pytest tests/ — 157 passed

Note

Medium Risk
Changes core LLM turn handling and default context behavior (compaction off unless configured), so long runs and training trajectories may diverge from prior releases; mistakes in overflow detection or checkpoint retry could drop history or end runs early.

Overview
Context compaction is opt-in instead of defaulting to a 256k token threshold. Enable with RLM_COMPACTION=1 or by setting RLM_SUMMARIZE_AT_TOKENS; when compaction is on but no explicit threshold is set, the engine discovers the model window via /models and compacts at window minus 16k (small windows keep at least half). Docs drop RLM_MAX_OUTPUT / RLM_MAX_TOOL_OUTPUT_CHARS in favor of a fixed 20KB head/tail truncation on tool results before they hit the chat.

Compaction logic moves into rlm.compaction (overflow heuristics, checkpoint prompts, truncation). The agent loop gains _complete: proactive compaction after large tool turns, reactive compact-and-retry on provider 400/413 context errors, and on finish_reason=length when usage crosses the threshold. Checkpoints retry up to three times with _last_good fallbacks, plain-text-only summaries (no tool calls / no reasoning channel), and CompactionFailed clean stops instead of treating every oversized body as fatal.

ExecutionPolicy.compaction and ACP/runtime snapshots expose the flag; semantic edge tracking can release and reclaim summary requests on resample. Tests cover overflow recovery, disabled compaction, discovered thresholds, and sub-agents.

Reviewed by Cursor Bugbot for commit f300615. Bugbot is set up for automated code reviews on this repo. Configure here.

mikasenghaas and others added 9 commits August 26, 2026 21:18
Keep ExecutionPolicy flat: a compaction toggle plus the existing
summarize_at_tokens threshold, instead of a nested config object.
Setting a threshold still implies compaction. The ACP session-meta
policy and the session snapshot flatten with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The OpenAI SDK cannot construct a bare dict from a response
(construct_type needs a parameterized mapping), so threshold
discovery raised ValueError past the APIError handler and killed
the engine on its first turn against a real server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The model can ignore tool_choice="none" on the checkpoint turn and
reply with a tool call and no text (observed ~6% of compactions on
deepseek-v4-flash) - the rebuilt branch then starts with no context.
Resample the checkpoint up to three times until it yields a text
summary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The failed checkpoints were not disobedience: the model understood
the request and chose to run one more state-gathering tool call
before summarizing, which the loop never grants it. Say explicitly
that the summary must come from the conversation as it stands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One checkpoint call per compaction - the hardened prompt is the
guard against tool-call replies. Also name estimated_tokens' input
for what it counts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mikasenghaas and others added 2 commits August 27, 2026 18:34
# Conflicts:
#	src/rlm/config.py
#	src/rlm/engine.py
Compact when 16k tokens remain below the context window instead of
at 90% of it - a fixed reserve keeps constant headroom on any
window size (small windows keep at least half). Truncate a tool
result over 10KB middle-out before it enters the conversation,
with a warning naming the original token count and line count, so
one giant output can never leap past the reserve and the model
knows what was cut. Matches Codex's output policy; the threshold
matches pi's reserve design. Drop the stale README rows for the
unimplemented RLM_MAX_OUTPUT knobs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mikasenghaas mikasenghaas changed the title feat: recover from context overflow feat: tool truncation + auto-compaction Aug 27, 2026
mikasenghaas and others added 2 commits August 27, 2026 21:32
Each marker now names the API whose error wording it matches, and
the unattributable generics are gone - "too many tokens" also
matches Bedrock throttling, and bare "context length"/"context
window" substrings matched more than they targeted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 413 markers could never fire: a 413 arrives as a plain
APIStatusError, not BadRequestError. Catch APIStatusError at the
compaction sites and gate overflow detection on a deterministic
status (400 or 413) so marker-shaped text in a transient failure
never triggers a compaction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
samsja added a commit that referenced this pull request Aug 28, 2026
## Summary

Hard-caps any single tool result entering the conversation at **10KB**,
middle-out (keep head+tail), with a warning header naming the original
size and line count:

```
Warning: truncated output (original token count: 12500)
Total output lines: 10001

<first 5KB>
[... 40000 bytes truncated ...]
<last 5KB>
```

Applies at the engine tool-result boundary — so it covers **all tools**
(`bash`, `edit`, and `ipython` cell output) uniformly.

## Scope: context only — tools yes, skills no

- The **session log keeps the full output** (audit trail unchanged).
- **Skill return values inside the kernel stay uncapped**: `out = await
bash(...)` holds the complete string for in-cell filtering; only what
the cell *prints* (the tool result) is subject to the cap.
Capture-then-filter workflows keep full fidelity — the cap only protects
the context window.

## Compatibility

The function is byte-compatible with the truncation in
[verifiers#2454](PrimeIntellect-ai/verifiers#2454)
(bash harness) and the copy bundled inside
[#147](#147)
(auto-compaction) — extracted standalone here so the cap can ship
independently; #147 can relocate/dedupe it when it lands.

Motivation from eval traces: unclipped tool results produced single-turn
context blowups (observed up to ~690k tokens from one `cat` on a large
file), which no compaction threshold can save you from after the fact.

Tests: truncation unit test added; 139 passed (6 pre-existing
`test_acp.py` env failures, same as clean main); ruff clean.
mikasenghaas and others added 3 commits August 28, 2026 21:16
Final compaction design: proactive at a fixed reserve below a known
context window, reactive on attributed 400/413 overflow errors. A
rejected checkpoint no longer sheds tool results - it falls back to
the last state that passed a threshold check, which by definition
holds a full reserve of room; an empty or tool-calling reply is
resampled, and after three failed attempts the run ends cleanly as
a trainable sample instead of crashing. An overflow with no history
beyond the task propagates. Tool truncation grows to 20KB, the
checkpoint prompt returns to the Codex wording, and the
threshold-learning regexes go away - compaction now requires a
known window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	src/rlm/config.py
#	src/rlm/engine.py
#	tests/test_acp.py
The raw cast_to parse breaks on one Python version or another: a
bare dict cannot be constructed on 3.13, and a parameterized dict
trips inspect.isclass on 3.10 (observed as ACP failures in
containers whose best Python is 3.10). The SDK's models.list keeps
provider extensions in each card's model_extra, on every version.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mikasenghaas and others added 7 commits August 28, 2026 22:05
A reasoning-parsed model (observed: Laguna via the glm45 parser) can
put the entire checkpoint reply in reasoning_content, leaving
content empty - every attempt then fails and the run ends as
compaction-failed despite a perfectly good summary. The checkpoint
asked for a summary, so when content is empty accept the reasoning
text as the summary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An unusable checkpoint reply (empty or tool-calling) finishes its
request without failing it, so the compaction still held the claim
and the resample died on "compaction already has a summary request".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vLLM 0.26 names the field "reasoning" and the SDK only keeps it in
model_extra, so the attribute lookup never saw it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A checkpoint reply that lives entirely in the reasoning channel is
resampled like an empty one - reasoning never enters the summary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review: last_good started at zero, so a first-turn checkpoint
rejection retried over an empty base - a summary of nothing with
the task gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review: an overflow on the post-compaction work call propagated out
of the loop and crashed the rollout. The rebuilt conversation is
sized to fit by construction, so if it still overflows there are no
moves left - convert it to the compaction-failed clean ending.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review: the post-tool snapshot was taken on a chars/4 estimate,
which can undercount dense content severalfold - the "good"
snapshot could itself be oversized, making the fallback identical
to the overflowing request. A state now becomes the fallback only
when the provider accepted that exact prompt with real usage below
the threshold, which lands the fallback before the tool results,
as designed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mikasenghaas
mikasenghaas marked this pull request as ready for review August 29, 2026 00:30
@mikasenghaas
mikasenghaas requested review from hallerite and samsja and removed request for samsja August 29, 2026 00:34
Comment thread src/rlm/engine.py
Comment thread src/rlm/engine.py
Comment thread src/rlm/compaction.py
mikasenghaas and others added 3 commits August 29, 2026 01:55
The move into compaction.py had replaced the checkpoint prompt with the
Codex template wording. Keep the actionable handoff prompt that main
already ships (runnable repro commands, pending edit calls, numbered
next steps) and keep the trailing no-tool-call instruction that stops
the model from answering the checkpoint with a tool call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three review findings:
- prompt() rollback now restores _last_good with the conversation, so a
  failed turn can no longer leave a fallback slice past the restored
  history.
- A follow-up prompt() floors _last_good at the turn's opening state, so
  a checkpoint fallback never drops the newest user instruction.
- discover_threshold no longer caches a failed /models listing; a
  transient failure at startup retries on the next engine instead of
  disabling compaction for the process lifetime.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An overflow on a conversation that a compaction already reduced to
[system, summary] re-raised the provider error, so the run failed
instead of ending as a clean compaction_failed like the in-cycle
retry path. Track that a compaction happened and convert that
overflow to CompactionFailed; the first-turn floor keeps raising.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7f6a408. Configure here.

Comment thread src/rlm/engine.py
The flag marks the live conversation as a compaction floor; a rolled-
back turn's compaction is no longer part of that conversation, so a
later overflow must propagate again instead of ending the run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hallerite added a commit that referenced this pull request Sep 1, 2026
max_tool_output_chars becomes max_tool_output_bytes and reuses the existing
head/tail truncation (PR #147's mechanism) as a budget override of the 10KB
default, instead of a second chars-based pass — a result could previously be
truncated twice with two stacked warning headers. Session logs keep the full
output; only the conversation copy is capped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
samsja
samsja previously approved these changes Sep 1, 2026
@mikasenghaas
mikasenghaas merged commit 4ef3438 into main Sep 1, 2026
9 checks passed
@mikasenghaas
mikasenghaas deleted the feat/context-compaction branch September 1, 2026 17:25
mikasenghaas added a commit to PrimeIntellect-ai/verifiers that referenced this pull request Sep 1, 2026
## Summary

- add the same optional `CompactionConfig` to the RLM harness as the
bash harness carries
- cross ACP with a flat policy: a `compaction` toggle plus
`summarize_at_tokens`
- pin merged nano-rlm compaction commit `4ef3438`

Builds on merged
[#2454](#2454), which
adds Bash compaction and the interception `/v1/models` relay.
Companion [nano-rlm
#147](PrimeIntellect-ai/nano-rlm#147) is merged.

## Breaking

- `RLMHarnessConfig.summarize_at_tokens` moves to
`RLMHarnessConfig.compaction.summarize_at_tokens` and no longer accepts
a `(lo, hi)` range.
- Leave `compaction` unset to disable proactive and reactive compaction.

## Verification

- `uv run pytest -q tests/v1` — passed; live E2E tests skipped without
`PRIME_API_KEY`
- `uv run pytest -q tests/v1/test_configs.py` — 12 passed
- `uv run ruff check verifiers/v1/harnesses/rlm/harness.py`
- `uv run ruff format --check verifiers/v1/harnesses/rlm/harness.py`

Terminal-Bench 2 e2e: 8 tasks, local vLLM `poolside/Laguna-XS-2.1` at
32k (glm45 reasoning + glm47 tool parsers), `compaction = {}` so the
engine discovers the threshold itself (`32768 − 16384 = 16384`). Trace
analysis of the pinned engine:

- Threshold discovery and the proactive trigger work through ACP:
compaction fired on the 3 episodes whose context crossed ~17k; episodes
that stayed below (0.7k-6.7k peaks) never compacted; 20KB tool
truncation visible where tool output was large.
- The runs surfaced and the pin fixes three integration bugs, each
verified against the failing trace: `/models` discovery crashing on
Python 3.10 containers (raw `cast_to` parse; now `models.list()`), and
two interactions with semantic-edge bookkeeping. A failed checkpoint
attempt and a resampled unusable reply each left the compaction's
summary-request claim held, which killed the retry with "compaction
already has a summary request".
- Laguna answers checkpoint prompts entirely in the reasoning channel,
so under the summaries-are-content-only rule its compactions exercise
the resample-then-end-cleanly path; summary carry-over across branches
was demonstrated on content-channel models (Qwen3-0.6B,
deepseek-v4-flash).
- A final combined verification run on a content-channel model is
pending before merge.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Breaking harness configuration and ACP runtime policy shape affect
rollout behavior and compaction timing; changes are localized to the RLM
harness but alter long-running agent context management.
> 
> **Overview**
> **RLM harness compaction** is restructured to match the bash harness:
a nested `CompactionConfig` with optional `summarize_at_tokens`, exposed
over ACP as `policy.compaction` (on/off) plus the threshold when set.
> 
> **Breaking config change:** `RLMHarnessConfig.summarize_at_tokens` is
removed in favor of `compaction`; the `(lo, hi)` per-task random range
and `summarize_threshold()` are dropped. **`compaction` unset** means
compaction is off; an **empty** `compaction` object enables automatic
thresholding (e.g. context window minus 16k when advertised).
> 
> The pinned **nano-rlm** ref updates to **`4ef3438`** for the merged
compaction engine. `_runtime_metadata` no longer takes `TaskData` since
thresholds are no longer task-index–seeded.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5f39bb2. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- Macroscope's pull request summary starts here -->
<!-- Macroscope will only edit the content between these invisible
markers, and the markers themselves will not be visible in the GitHub
rendered markdown. -->
<!-- If you delete either of the start / end markers from your PR's
description, Macroscope will append its summary at the bottom of the
description. -->
> [!NOTE]
> ### Add `CompactionConfig` to `RLMHarness` and remove per-task
threshold randomization
> - Introduces `CompactionConfig` (derived from `BaseConfig`) with an
optional `summarize_at_tokens: PositiveInt` field, replacing the flat
`summarize_at_tokens` tuple-range field on `RLMHarnessConfig`.
> - Removes `RLMHarness.summarize_threshold`, which previously computed
per-task randomized thresholds seeded by task index. `_runtime_metadata`
now reads thresholds directly from `self.config.compaction` and emits a
boolean `compaction` flag in the session policy.
> - Changes the default `version` git ref for `RLMHarnessConfig` to
`4ef3438`.
> - Behavioral Change: `summarize_at_tokens` no longer accepts `(lo,
hi)` tuple ranges; callers must provide a single `PositiveInt` inside
`CompactionConfig`. The `data` parameter was removed from
`RLMHarness._runtime_metadata`.
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized
5f39bb2.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->
hallerite added a commit that referenced this pull request Sep 1, 2026
Rebased onto auto-compaction (#147) and consolidated. Three optional
ExecutionPolicy caps, configured via the ACP runtime-v1 contract:

- max_total_turns: tree-total work-loop call budget (compaction calls
  excluded), counted live by the supervisor; every engine stops gracefully
  before its next call once spent (stop_reason=max_total_turns).
- max_total_tokens: tree-total NEW-token budget (completion + uncached
  prompt per call - the cached prefix re-billed each call is not new work);
  same graceful stop, and the supervisor refuses new sub-agent spawns.
- max_tool_output_bytes: byte budget for one tool result entering the
  conversation, overriding the built-in 20KB default (same middle-out
  mechanism, one truncation pass).

Capped stops report true turn counts and salvage a final answer (this
prompt's last assistant text, else the compaction handoff summary, else a
bracketed marker). Without a supervisor the engine enforces the budgets
with its own counters (a no-broker session is its own whole tree), and a
spent cap suppresses proactive compaction (the reactive overflow path
stays available).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hallerite added a commit that referenced this pull request Sep 1, 2026
Rebased onto auto-compaction (#147) and consolidated. Three optional
ExecutionPolicy caps, configured via the ACP runtime-v1 contract:

- max_total_turns: tree-total work-loop call budget (compaction calls
  excluded), counted live by the supervisor; every engine stops gracefully
  before its next call once spent (stop_reason=max_total_turns).
- max_total_tokens: tree-total NEW-token budget (completion + uncached
  prompt per call - the cached prefix re-billed each call is not new work);
  same graceful stop, and the supervisor refuses new sub-agent spawns.
- max_tool_output_bytes: byte budget for one tool result entering the
  conversation, overriding the built-in 20KB default (same middle-out
  mechanism, one truncation pass).

Capped stops report true turn counts and salvage a final answer (this
prompt's last assistant text, else the compaction handoff summary, else a
bracketed marker). Without a supervisor the engine enforces the budgets
with its own counters (a no-broker session is its own whole tree), and a
spent cap suppresses proactive compaction (the reactive overflow path
stays available).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hallerite added a commit that referenced this pull request Sep 1, 2026
Rebased onto auto-compaction (#147) and consolidated. Three optional
ExecutionPolicy caps, configured via the ACP runtime-v1 contract:

- max_total_turns: tree-total work-loop call budget (compaction calls
  excluded), counted live by the supervisor; every engine stops gracefully
  before its next call once spent (stop_reason=max_total_turns).
- max_total_tokens: tree-total NEW-token budget (completion + uncached
  prompt per call - the cached prefix re-billed each call is not new work);
  same graceful stop, and the supervisor refuses new sub-agent spawns.
- max_tool_output_bytes: byte budget for one tool result entering the
  conversation, overriding the built-in 20KB default (same middle-out
  mechanism, one truncation pass).

Capped stops report true turn counts and salvage a final answer (this
prompt's last assistant text, else the compaction handoff summary, else a
bracketed marker). Without a supervisor the engine enforces the budgets
with its own counters (a no-broker session is its own whole tree), and a
spent cap suppresses proactive compaction (the reactive overflow path
stays available).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mikasenghaas added a commit to PrimeIntellect-ai/prime-rl that referenced this pull request Sep 1, 2026
## Summary

- advance the `deps/verifiers` submodule from `e2103d6` to `d4a2177`
- include merged Bash and RLM context compaction from verifiers #2454
and #2459
- pick up nano-rlm compaction commit `4ef3438` through the default RLM
harness pin
- refresh `uv.lock` for verifiers' `aiohttp>=3.14.1` requirement
- migrate three RLM examples to `compaction.summarize_at_tokens`; use
the former range's `98_304` midpoint
- include the optional ACP semantic-edge and shared harness utility
changes already on verifiers `main`

Companions: [verifiers
#2454](PrimeIntellect-ai/verifiers#2454),
[verifiers
#2459](PrimeIntellect-ai/verifiers#2459), and
[nano-rlm #147](PrimeIntellect-ai/nano-rlm#147).

## Breaking

- RLM harness configs must move `summarize_at_tokens` to
`compaction.summarize_at_tokens`.
- Leave `compaction` unset to disable proactive and reactive compaction.

## Verification

- `git diff --check`
- `uv lock`
- `uv lock --check`
- `uv run pytest -q tests/unit/test_configs.py` — 133 passed
- `git submodule status deps/verifiers` —
`d4a217794fc0bfd70369a8230e56653c193da8ce`
- verified that `d4a2177` descends from the previous `e2103d6` pin

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Submodule bump plus a breaking harness config shape affects all RLM
runs still using the old `summarize_at_tokens` field; example migrations
are mechanical but custom configs must be updated.
> 
> **Overview**
> Advances the **`deps/verifiers`** submodule to pick up merged Bash/RLM
**context compaction** (and related harness defaults), with
**`uv.lock`** refreshed so **`aiohttp`** meets the new **`>=3.14.1`**
floor.
> 
> **Breaking for RLM harness TOML:** flat
**`env.agent.harness.summarize_at_tokens`** is replaced by
**`env.agent.harness.compaction.summarize_at_tokens`**. The three
advanced examples (**`glm-4.5-air/search`**, **`glm-4.5-air/terminal`**,
**`nemotron-3-super/swe`**) are updated accordingly—train sources that
used a two-threshold list **`[65536, 131072]`** now use a single
**`98304`** threshold; eval sources keep **`98304`** but under the
nested **`compaction`** key.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7429aba. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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