Skip to content

Improve DART 6 deformable-body performance and soft contact#3382

Open
jslee02 wants to merge 133 commits into
release-6.20from
wp-db-native-soft-fallback
Open

Improve DART 6 deformable-body performance and soft contact#3382
jslee02 wants to merge 133 commits into
release-6.20from
wp-db-native-soft-fallback

Conversation

@jslee02

@jslee02 jslee02 commented Jul 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Add opt-in adaptive soft-contact activation and opt-in soft face-interior
    contact coverage for DART 6.
  • Extend deformable-body correctness, stability, determinism, allocation,
    benchmark, and demo coverage.
  • Retain measured performance improvements while preserving existing public
    layouts and default behavior.

This is a representative DART 6 release slice, not a claim of complete paper
parity, successful multicore scaling, or a native-default deformable backend.

Motivation / Problem

DART 6 SoftBodyNode had a useful point-mass soft-body model, but lacked
several release-quality pieces:

  • contact-local adaptive activation modeled after Jain and Liu;
  • coverage for primitives intersecting a soft-face interior without enclosing
    a vertex;
  • representative equation, energy, force/CoP, determinism, and allocation
    gates;
  • reproducible headless performance tooling and flagship demonstrations; and
  • durable evidence separating completed work from paper-scale, scaling, and
    native-default follow-ups.

The implementation must preserve DART 6 API/ABI compatibility. New behavior
therefore remains opt-in and implementation state stays out of public class
layouts.

Before / After

Area Before After
Soft-contact activation Every soft point mass remained active. Users can opt into contact-local activation with ring, linger, and tolerance controls; default-off behavior retains the all-active path.
Soft face-interior contact A primitive could intersect a soft face without enclosing a vertex and miss the contact. Users can opt into DART-owned, BVH-pruned sphere/box face-interior coverage.
Representative demos There were no adaptive-contact or soft-worm flagship scenes. adaptive_soft_contact and soft_worm are integrated into dart-demos; no new standalone GUI executables remain.
Release evidence Performance, correctness, and deferred parity claims were not collected in one release packet. #3382 carries a tested representative slice while keeping failed winner, scaling, native-default, and paper-parity gates explicit.

Changes / Key Changes

  • Adaptive soft-contact activation (WP-DB.05, opt-in)

    • Adds non-virtual SoftBodyNode controls for contact seeding, ring
      expansion, linger, and rest tolerances.
    • Treats inactive points as rigidly lumped mass and inertia on their parent.
    • Preserves the previous all-active path when disabled.
  • Soft face-interior contacts (WP-DB.08, opt-in)

    • Adds BVH-pruned sphere/box feature tests for contacts occurring between
      soft vertices.
    • Keeps the feature disabled by default.
    • Adds contact geometry, ordering, determinism, and allocation coverage.
  • Equation and stability coverage (WP-DB.02/.04)

    • Extends mass, augmented-mass, inverse-matrix, gravity, combined-force, and
      external-force checks.
    • Adds a regression proving retained point-mass accelerations cannot affect
      public mass-matrix columns.
    • Invalidates articulated-inertia caches when adaptive activation changes
      mode and adds an immediate-query regression.
    • Adds energy-growth, contact-force/CoP, LCP reset-proxy, and threaded
      final-state gates.
  • Performance and memory work (WP-DB.06/.07)

    • Retains FCL soft-mesh refresh, point-mass phase-access, aggregation,
      empty-solve, allocation, and native-fallback improvements that passed
      correctness gates.
    • Records retained SoA mirrors as a measured rejection and contiguous
      PointMass storage as deferred redesign work.
    • Adds a revision-pinned paired detector runner with checksum, load, thermal,
      affinity, raw-row, and completion-marker requirements.
    • Stabilizes the runner's timeout test without weakening the production
      process-group wall-time guarantee.
  • Native collision direction (WP-DB.08)

    • Adds and hardens DART-owned soft primitive/soft contact paths and
      direct-native fallback support.
    • Keeps native-preferred/default work open pending broader coverage, scaling,
      downstream gates, and reproducible paired evidence.
    • Preserves the staged follow-up contract in
      docs/design/dart6_deformable_body.md.
  • Flagship demos (WP-DB.09)

    • Integrates adaptive_soft_contact and soft_worm into the consolidated
      dart-demos Soft Bodies catalog; the separate executables are removed.
    • Retains adaptive activation/ring/linger controls and worm gait controls in
      the common ImGui host.
    • Uses the shared scene-selection and headless-capture route, with GUI-free
      model tests preserving the adaptive comparison and worm-locomotion gates.

Performance evidence and limitation

The recorded pre-merge matrix at
.benchmark_results/wp-db-final-6cfa4fa-parent-c743a45-base-72ebe16/
compares branch 3340e1d3df2 with base 72ebe164e8c.

  • The FCL lane improves all eight tracked scene/thread rows by 36.3%-40.1%.
  • The DART detector improves seven of eight rows by 8.4%-24.2%;
    adaptive_deformable/1 is +8.4% in the noisy block-ordered run.
  • The machine-readable evaluator is FAIL because direct native exceeds the
    2% tie tolerance on several rows.
  • Manual interleaved rows support a possible tie on two single-thread scenes
    only; they do not override the evaluator or cover the full failed gate.

A reviewed paired runner now exists, but every exact-head attempt was stopped
in preflight because the shared host failed its load/thermal/workload gates.
The latest clean-source attempt at af7ae4ccedde recorded 156/156 load
failures, 151 thermal failures, 110 sibling-workload failures, zero clean polls,
and no timing rows or COMPLETE.json.

Accordingly, no final native/DART winner claim is made. Closeout still requires
either a conformant paired artifact or explicit maintainer acceptance of the
documented limitation.

Scope decisions and follow-ups

Maintainer-approved deferrals cover the paper-scale volumetric-FEM characters,
SIMBICON/controller rows, and hand-manipulation scenes. They do not cover the
four-link flexible-rigid-foot versus deformable-foot comparison.

Still open:

  • formal sign-off on the competitive-implementation envelope;
  • implement or explicitly defer the flexible-foot comparison;
  • WP-DB.07 larger-workload multicore scaling;
  • WP-DB.08 native-owned coverage/default work;
  • a separate main fix corresponding to release commit 10c6b6055e4; and
  • final paired benchmark evidence or an approved disposition.

Testing

Current exact head: 351d4a04fb3fc070e5c1713dba23a32738e49c8c.
It includes origin/release-6.20@6a1d377f61631f03880a88bd21f2e7e803696c1a
through merge commit 416266f60e484e2a6359fcdc8fecdaa718f3a3ff,
same-count soft-face cache repair e973a75fb96, Gazebo hot-path correction
c41f273d271, preparation-state review fix 891f43fd590, and the evidence
refresh at the current head. The base merge also carries #3395's Windows CI
/GL//LTCG correction.

Windows and Codecov follow-up

At pre-follow-up head b172b2ee1db, 21 checks passed, one failed, and one
was skipped. Windows Release completed 150/151 tests; the only failure was
SoftDynamicsTest.restingSoftContactForceAndCenterOfPressureAreSmooth in
legacy FCL's default adaptive lane, where maximum per-step CoP motion was
0.12115883267368355 m against the former 0.11 m bound.

Test-only commit 50a254e7e56 calibrates the legacy-FCL bound to 0.13 m,
just above one 0.125 m scene mesh interval. The native bound remains
0.02 m; percentile-force, support-loss, spike, and finite-state guards are
unchanged, and the per-step CoP assertion remains in place. This changes no
runtime behavior, API, ABI, or default simulation semantics. Windows Release
passed the calibrated suite on 05d9de6e3fb before the ABI follow-up.

Codecov passed both GitHub checks on b172b2ee1db: patch coverage was
94.34783% with 143 uncovered changed lines, while project coverage was
75.17% versus 73.90% (reported as +1.26 percentage points). The red
patch marker in the bot comment is informational under codecov.yml; it is
not a required threshold.

Detector ABI follow-up

Fresh Codex review of 05d9de6e3fb identified private collision-thread
fields in the installed, derivable DARTCollisionDetector class. Those fields
originated in prior release commit 3e13581f67d, but they are absent from
released tag v6.19.4 and enlarged the x86-64 class from 32 to 48 bytes.

Commit 9a6796596bc restores the released header layout and implicit-destructor
surface. DART-specific thread-pool/count and soft-contact state now lives in a
forwarding manager behind the base class's existing collision-object-manager
pointer. The pool address remains stable, resize is serialized, published
options are atomic, clone state remains independent, and compile-time
size/alignment guards prevent renewed exported-layout growth.

ABI follow-up validation:

  • no-cache focused dependency build — PASS
  • test_DARTCollisionDetector — PASS (22/22)
  • test_Collision — PASS (52/52)
  • test_NonFiniteContact — PASS (4/4)
  • exact v6.19.4-header/new-library ABI canary — PASS (20/20 processes;
    legacy/current detector sizes both 32 bytes)
  • pixi run lint, git diff --check, and pixi run check-ai-commands — PASS
  • independent implementation reviews and evidence reviews — CLEAN x2 each

The ABI compatibility repair has a DART 6.20 changelog entry linked to #3382.

Same-count soft-topology cache follow-up

Fresh review of merge head 416266f60e4 found that changing a
SoftBodyNode face ordering without changing point/face counts left the
DART fallback object's cached face identities, first-face map, and BVH
topology stale. Commit e973a75fb96 compares the cached and current face
indices after the existing O(1) topology guards and reuses the existing
cache/BVH rebuild path when they differ.

The controlled regression failed before the fix (triID2 remained stale at
0 instead of moving to 2) and passed afterward. It also exercises a
vertex contact to guard the first-face map.

Exact-head local validation:

  • pixi run lint — PASS
  • no-cache test_DARTCollisionDetector — PASS (23/23)
  • no-cache INTEGRATION_StepAllocation, test_Collision, and
    test_NonFiniteContact — PASS
  • no-cache pixi run test — PASS (154/154)
  • git diff --check and post-repair Ninja no-work check — CLEAN
  • independent correctness/API/ABI/allocation/test review — CLEAN

The fix is implementation-only, allocation-free, and does not change public
API, ABI, or default contact-enable behavior. The unchanged-cache path adds
an early-exit O(F) integer comparison alongside the existing O(P) point
geometry scan.

Gazebo zero-overhead follow-up

The PR previously put a process-wide ConstraintSolverClearStateRegistry
lookup, mutex, and hash-table access on every ConstraintSolver::solve()
call. Commit c41f273d271 removes that unconditional cost. Previous-step
cleanup is derived from mActiveConstraints and mCollisionResult, which
the solver already retains, while newly inserted skeletons are sanitized
outside the stepping hot path. The common contact cleanup remains
branch-free per skeleton.

The audited downstream path is the real plugin boundary:

  • gz-physics 8 constructs GzOdeCollisionDetector by default, and gz-sim 9
    reaches DART through that gz-physics plugin;
  • the optional native/FCL/Bullet soft-mesh paths are unreachable from that
    default rigid-world route;
  • neither inspected downstream calls the changed DART inverse-matrix APIs;
    and
  • production libdart has no clear-state-registry symbol, so the removed
    registry no longer adds unconditional synchronization to a one-thread
    Gazebo step.

A production-equivalent plugin-boundary A/B used GCC 15.2, Release -O3,
profiling off, SIMD off, CPU 24, 1,000 warmup steps, and 20 interleaved
base/head pairs. Timing covered only gz-physics World::Step:

Workload Base mean Head mean Change Pair result
Empty world, 1,000,000 steps 988.435 ms 741.334 ms -24.999% head won 20/20
Falling/contact, 50,000 steps 1113.639 ms 1112.817 ms -0.074% head won 14/20

The corresponding medians improved 24.773% and 0.816%. This timing does not
claim mathematical instruction-for-instruction identity; the structural
audit establishes removal of the unintended unconditional work, and the
plugin-boundary A/B establishes no measured downstream regression.

Exact local validation:

  • focused constraint/world/collision CTest gate — PASS (6/6)
  • exact formatted test_ConstraintSolver — PASS (57/57)
  • native-soft steady-state allocation gate — PASS (14/14, zero allocations)
  • DART_DISABLE_COMPILER_CACHE=ON pixi run test — PASS (154/154)
  • gz-physics functional/performance — PASS (199/199 + 4/4)
  • gz-sim source-built-DART integration — PASS (1/1)
  • pixi run lint, pre-commit Tier-0 gate, and git diff --check — PASS

Fresh review of c41f273d271 found that prepareForSimulation() could
erase the retained active-set signal after a manual-only solve, preventing
the next solve() from clearing the prior constraint impulse. Commit
891f43fd590 preserves the active set and its classification flags across
the preparation-only passes. The regression failed before the fix and
passed afterward. Because solve() and the production gz steady-state path
are unchanged, the plugin-boundary A/B above remains an exact comparison of
the affected hot-path code.

No new changelog entry is needed: #3382 already documents the user-visible
deformable feature and ABI repair, while this follow-up removes an internal
implementation cost without adding an API or user-visible behavior.

Local validation on the merged calibration candidate

  • pixi run lint — PASS
  • pixi run check-ai-commands — PASS (23 shared capabilities)
  • DART_DISABLE_COMPILER_CACHE=ON pixi run build — PASS (292/292)
  • DART_DISABLE_COMPILER_CACHE=ON pixi run test — PASS (154/154)
  • complete test_SoftDynamics — PASS (25/25)
  • calibrated case — PASS (20/20 repeated runs)
  • pixi run -e gazebo test-gz — PASS (gz-physics 199/199 functional and
    4/4 performance checks; gz-sim source-built-DART integration 1/1)
  • git diff --check — PASS
  • independent reviews — CLEAN x2 for the calibration, CLEAN x2 for the ABI
    implementation, and CLEAN x2 for the current task/evidence refresh

Latest-base and exact-head validation

  • merge of origin/release-6.20@6a1d377f616 through 416266f60e4
    CLEAN, no manual conflict resolution
  • independent semantic audit — CLEAN: the 81-path result is the exact union
    of both parent deltas; the only overlaps (ci_windows.yml and
    CHANGELOG.md) preserve both payloads with no conflict markers
  • pre-review-fix merged candidate with assertions enabled,
    DART_BUILD_GUI_OSG=OFF, and DART_BUILD_DARTPY=OFF — PASS (154/154)
  • prior head e973a75fb96, normal Release, compiler cache disabled and
    launchers empty — lint PASS and full CTest PASS (154/154)
  • implementation head 891f43fd590, compiler cache disabled — full CTest
    PASS (154/154), focused solver PASS (57/57), allocation gate PASS (14/14),
    gz-physics PASS (199/199 + 4/4), and gz-sim PASS (1/1)
  • current evidence head 351d4a04fb3 differs from the validated
    implementation only in task documentation
  • git diff --check, lint, and both staged pre-commit safety gates — CLEAN

Visual verification

No new visual capture is claimed for the 0.11 m to 0.13 m test
calibration: it changes a numeric assertion, not simulation or rendering
behavior, and an image cannot prove a per-step CoP limit. Historical
dart-demos visual commands and verdicts are recorded in the task evidence,
but their temporary /tmp captures are not durable current artifacts.
GUI-free model gates remain the numerical scene oracle.

Manual demo commands:

pixi run demos --scene adaptive_soft_contact
pixi run demos --scene soft_worm

./build/default/cpp/Release/bin/dart-demos \
  --scene adaptive_soft_contact --headless --steps 500 --shot adaptive.png
./build/default/cpp/Release/bin/dart-demos \
  --scene soft_worm --headless --steps 3000 --shot worm.png

Published head 351d4a04fb3 supersedes the prior hosted matrix; only its
checks and review are authoritative now. Its validated implementation parent
is 891f43fd590; the final commit changes task evidence only. Hosted
gz-physics/gz-sim passed on c41f273d271, whose fresh Codex review found the
preparation-state issue addressed by 891f43fd590. Hosted CI for earlier
head e973a75fb96 was terminal: 18 GitHub Actions checks passed, one expected
API-documentation deploy was skipped, and both Read the Docs contexts passed.
Merging remains unauthorized.

Previous exact head 416266f60e4 was fully terminal, including both Codecov
statuses. Its updated Codecov comment reported 94.42919% patch coverage with
142 changed lines missing and 75.17% project coverage versus 73.87% on the base
(+1.29 percentage points); patch coverage remains informational under
codecov.yml.

The prior e973a75fb9 Codex review completed clean at issue comment
5041775831. The thread-aware audit was 16/16 resolved before publishing
c41f273d271; its new preparation-state thread is addressed by
891f43fd590 without an inline reply. The current head requires its own
top-level review, and live review status is authoritative.

Breaking Changes

  • None
  • Existing behavior remains the default.
  • New controls are additive and non-virtual.
  • New runtime state does not change public class layouts.

Related Issues / PRs (backports)


Checklist

  • Milestone set (DART 6.20.0)
  • CHANGELOG.md updated
  • Unit/integration tests added for new functionality
  • New C++ methods documented in public headers and task/design docs
  • Python bindings not included; the new controls are currently C++-only

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: b172b2ee1d

ℹ️ 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".

jslee02 commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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

std::unique_ptr<CollisionThreadPool> mCollisionThreadPool;
std::size_t mNumCollisionThreads{1u};

P1 Badge Keep DARTCollisionDetector state out of the ABI

When a downstream application or plugin is built against the previous DART 6.20 headers but loaded with this library, these new private members change sizeof(DARTCollisionDetector) and the derived-class layout for an exported installed class. The same commit uses side registries/static assertions elsewhere to preserve release-branch ABI, so the thread-count/thread-pool state should follow that pattern instead of adding storage to the public header.

ℹ️ 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".

jslee02 commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: ecd3f47882

ℹ️ 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".

@jslee02

jslee02 commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@jslee02

jslee02 commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 416266f60e

ℹ️ 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 dart/collision/dart/DARTCollisionObject.cpp
@jslee02

jslee02 commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: e973a75fb9

ℹ️ 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".

jslee02 commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: c41f273d27

ℹ️ 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 dart/constraint/ConstraintSolver.cpp

jslee02 commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

jslee02 added 4 commits July 23, 2026 10:00
Record the two independent role-separated reviews (correctness APPROVE;
semantic-equivalence EQUIVALENT-AND-CORRECT) on head 351d4a0 for the
ConstraintSolver registry-removal and preparation-state fix, standing in for
the weekly-limited Codex code review. Note the spurious non-required AppVeyor
status and the optional non-blocking hardening follow-ups.

Record the 2026-07-23 maintainer directive elevating the task to full
two-paper parity (correctness and performance, no compromise) plus zero
rigid-body overhead, retracting the 2026-07-11 deferral list, via ABI-safe
additive work on release-6.20 in a ~3-PR structure, with a research-and-propose
milestone plan as the next step.
Accepted 2026-07-23 plan for full Kim/Pollard + Jain/Liu parity (correctness and
performance, no compromise) plus zero rigid-body overhead, as ABI-safe additive
work on release-6.20 in a ~3-PR structure. Grounds the ABI-safe FEM extension
design (no FEM exists in DART today; integrate via a custom FemBodyNode's
existing virtuals / ConstraintBase / subclassed ConstraintSolver rather than
SoftBodyNode's ABI-breaking Skeleton-registry pattern) and the Jain/Liu
controller/model reuse (existing SIMBICON controller + soft-feet Atlas asset).
First build step is M2.0: prototype and pick the FEM integration seam while
proving pure-rigid determinism and zero overhead. Point PLAN-622 at the plan.
The ABI-safe per-step FEM integration hook is a custom constraint::ConstraintBase
whose update() ConstraintSolver::updateConstraints() calls unconditionally every
solve() (ConstraintSolver.cpp:1077, before the isActive() LCP gate), staying out
of the LCP with isActive()==false. A throwaway prototype (single explicit-Euler
particle one-way spring-coupled to a free rigid body) proved the hook runs
200/200, integrates deterministically, and leaves the rigid trajectory
bit-identical (zero perturbation) while touching no production code -- confirming
additive-on-release-6.20 is feasible. Two-way FEM->rigid coupling must use LCP
participation or caller-driven force before step() because mid-solve addExtForce
is cleared at World.cpp:1378. Records the seam, the coupling routes, zero-rigid-
overhead/determinism, and ABI-safety; updates RESUME next steps to PR-2 M2.1 and
PR-3a soft-foot.
Record the maintainer's 2026-07-23 sign-off of the competitive-implementation
envelope (in-tree backends + normalized paper metrics; external engines out of
scope) as the performance-acceptance bar. Add the PR-3a kickoff spec for the
Jain/Liu biped-push-recovery row: reuse the GUI-free atlas_simbicon controller
with the soft-feet Atlas asset, 3-part model/scene/test pattern, CMake wiring,
and rigid-vs-soft push-recovery/contact-count acceptance gates.
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