Skip to content

feat(hodlmm-risk): add HODLMM volatility risk monitoring skill#224

Closed
locallaunchsc-cloud wants to merge 11 commits intoaibtcdev:mainfrom
locallaunchsc-cloud:main
Closed

feat(hodlmm-risk): add HODLMM volatility risk monitoring skill#224
locallaunchsc-cloud wants to merge 11 commits intoaibtcdev:mainfrom
locallaunchsc-cloud:main

Conversation

@locallaunchsc-cloud
Copy link
Copy Markdown

New Skill: hodlmm-risk

Adds a read-only HODLMM volatility risk monitoring skill for Bitflow DLMM pools. This skill provides risk intelligence that other agents can call before adding, holding, or withdrawing HODLMM liquidity.

Subcommands

  • assess-pool - Computes volatility score (0-100), regime classification (calm/elevated/crisis), and position-sizing signals for a HODLMM pool
  • assess-position - Scores an existing LP position's drift from active bin, concentration risk, and recommends hold/withdraw/rebalance
  • regime-history - Returns a volatility regime snapshot with trend indicator

Risk Metrics

  • Bin spread (normalized range of non-empty bins)
  • Reserve imbalance ratio (X vs Y token skew)
  • Active bin concentration (liquidity dispersion)
  • Weighted volatility score combining all three signals

Key Properties

  • Read-only - no wallet or funds required
  • Mainnet-only - uses Bitflow BFF API public endpoints
  • Uses shared BitflowService from src/lib/services/bitflow.service.ts
  • Outputs single JSON objects per the repo convention

Files Added

  • hodlmm-risk/SKILL.md - Skill frontmatter and documentation
  • hodlmm-risk/AGENT.md - Agent operation rules and safety checks
  • hodlmm-risk/hodlmm-risk.ts - Commander CLI with 3 subcommands

Use Case

LP agents should call assess-pool before any bitflow add-liquidity-simple operation. If regime is crisis, the agent should not add liquidity. If elevated, reduce exposure per signals.maxExposurePct.

Copy link
Copy Markdown
Contributor

@arc0btc arc0btc left a comment

Choose a reason for hiding this comment

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

Adds a read-only HODLMM volatility risk monitoring skill — pool bin spread, reserve imbalance, and concentration metrics wrapped in a clean Commander CLI. The concept is solid and the integration with BitflowService follows repo conventions.

What works well:

  • Parallel Promise.all() for API calls in all three subcommands — right pattern for independent fetches
  • Clean separation of computePoolRiskMetrics and computeSignals — easy to reason about and test independently
  • Network guard at the top of each action is clear and consistent
  • Error handling for "No bins returned" and "Address has no position" covers the obvious API edge cases

[blocking] Empty bins crash: Math.min(...[]) produces Infinity when all bins have zero reserves (hodlmm-risk/hodlmm-risk.ts:61–66)

If nonEmptyBins is empty (pool just created, fully withdrawn, or API returns all-zero reserves), binIds is []. Spreading an empty array into Math.min/Math.max returns Infinity/-Infinity, making binSpread produce NaN. That NaN propagates into volatilityScore and regime, giving the calling agent a nonsensical signal.

  const nonEmptyBins = bins.filter(
    (b) => Number(b.reserve_x) > 0 || Number(b.reserve_y) > 0
  );
  if (nonEmptyBins.length === 0) {
    throw new Error("No active liquidity in this pool — all bins are empty");
  }
  const binIds = nonEmptyBins.map((b) => b.bin_id);

[blocking] regime-history is a stub but SKILL.md advertises it as multi-sample (hodlmm-risk/hodlmm-risk.ts:251–295, hodlmm-risk/SKILL.md)

The CLI accepts --samples <count> (SKILL.md documents default 10, max 50, example shows 10 points returned), but the implementation ignores the argument and always returns exactly 1 snapshot with trend: "stable" hardcoded. An agent calling regime-history --samples 10 expecting a trend signal will always see "stable" regardless of actual market movement — a false safety signal in elevated/crisis conditions.

Two options:

  1. Implement actual multi-sample behavior (requires caching or repeated API polling)
  2. Rename to regime-snapshot, remove --samples, update SKILL.md example to show samples: 1, and add a note that trend history requires an external time-series store

Until this is resolved, agents should not rely on trend output from regime-history. The current code comment acknowledges this ("currently returns 1 live snapshot") but the public interface doesn't make it obvious.


[suggestion] driftScore uses average bin offset but reports nearest offset (hodlmm-risk/hodlmm-risk.ts:225–235)

driftScore is derived from avgOffset (average distance across all position bins from active bin), but the output field nearestPositionBinOffset reports the minimum. These measure different things. A position spread across bins 440–460 with active bin at 447 has a low nearestOffset (0) but potentially high avgOffset. Calling agents comparing driftScore to nearestPositionBinOffset will get confusing results. Consider either:

  • Deriving driftScore from nearestOffset (more conservative — penalizes entire position moving out of range), or
  • Exposing avgBinOffset alongside nearestPositionBinOffset so the caller can see what's driving the score

[nit] SKILL.md JSON example has a typo in the output key (hodlmm-risk/SKILL.md:58)

"safeTo AddLiquidity" (space in the key) should be "safeToAddLiquidity".


Code quality notes:

  • computePoolRiskMetrics could be exported and unit-tested independently — the pure-function design is good, worth calling out in SKILL.md as testable
  • The three weight constants (40/30/30 for spread/imbalance/concentration) are undocumented magic numbers. A brief comment explaining the weighting rationale would help future contributors recalibrate without guessing
  • regime-history accepting but silently ignoring --samples > 1 is a footgun. If the stub path stays, add if (parseInt(opts.samples) > 1) throw new Error("Multi-sample history not yet implemented") to fail loudly rather than return misleading single-point data

Operational context: We run the defi-bitflow skill in production against these same Bitflow BFF endpoints. The getHodlmmPool/getHodlmmPoolBins APIs do return empty bins periodically for low-liquidity pools — the empty-bins guard isn't theoretical.

- Fix empty bins crash: guard nonEmptyBins.length === 0
- Rename regime-history to regime-snapshot, remove --samples
- Add avgBinOffset to assess-position output
- Document volatility weight constants (40/30/30)
- Bump to v0.2.0
sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 25, 2026
Adds read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands:
- list-pools: list all active HODLMM pools
- assess-pool: compute volatility score (0-100) and regime classification
- assess-position: evaluate LP position drift and concentration risk
- regime-history: scan all pools sorted by risk level

Risk model weights three signals:
- Bin spread (30%): fraction of bins with liquidity — low = risky
- Reserve imbalance (40%): |X_usd - Y_usd| / total — high = skewed pool
- Active bin concentration (30%): active bin share of total liquidity

Regime classification:
- calm (0-33): proceed normally
- elevated (34-66): reduce exposure per maxExposurePct signal
- crisis (67-100): do not add liquidity

Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 25, 2026
Adds read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands:
- list-pools: list all active HODLMM pools
- assess-pool: compute volatility score (0-100) and regime classification
- assess-position: evaluate LP position drift and concentration risk
- regime-history: scan all pools sorted by risk level

Risk model weights three signals:
- Bin spread (30%): fraction of bins with liquidity
- Reserve imbalance (40%): |X_usd - Y_usd| / total
- Active bin concentration (30%): active bin share of total

Regime: calm (0-33) / elevated (34-66) / crisis (67-100)
Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
@locallaunchsc-cloud
Copy link
Copy Markdown
Author

Update: Added hodlmm-rebalancer skill + lp-rebalancer agent config

This PR now also includes a second skill: hodlmm-rebalancer — an autonomous LP position rebalancer for Bitflow HODLMM pools.

New Skill: hodlmm-rebalancer

Consumes hodlmm-risk assessments and bitflow bin/position data to autonomously manage HODLMM liquidity positions.

Subcommands:

  • run — Executes a full rebalance cycle: assess risk → decide action → execute via bitflow
  • configure — Adjusts rebalancer parameters (exposure, bin width, thresholds)
  • history — Reviews past rebalance actions for a pool

Decision actions: add, reduce, withdraw, rebalance, hold, skip, emergency-withdraw

Files Added:

  • hodlmm-rebalancer/SKILL.md — Skill frontmatter and documentation
  • hodlmm-rebalancer/AGENT.md — Agent operation rules and safety checks
  • hodlmm-rebalancer/hodlmm-rebalancer.ts — Commander CLI with 3 subcommands
  • aibtc-agents/lp-rebalancer/README.md — Agent configuration

Relationship to hodlmm-risk: The rebalancer depends on hodlmm-risk assess-pool for regime classification. Crisis regime triggers emergency withdrawal; elevated regime reduces exposure; calm regime allows normal operations.

sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 25, 2026
Read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands: list-pools, assess-pool, assess-position, regime-history
Risk model: bin spread (30%) + reserve imbalance (40%) + active bin concentration (30%)
Regime: calm (0-33) / elevated (34-66) / crisis (67-100)
Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
@locallaunchsc-cloud
Copy link
Copy Markdown
Author

@arc0btc Hey, just following up — I’ve addressed all the requested changes. When you get a chance, could you re-review? Thanks!

sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 25, 2026
Adds read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands:
- list-pools: list all active HODLMM pools
- assess-pool: compute volatility score (0-100) and regime classification
- assess-position: evaluate LP position drift and concentration risk
- regime-history: scan all pools sorted by risk level

Risk model weights three signals:
- Bin spread (30%): fraction of bins with liquidity — low = risky
- Reserve imbalance (40%): |X_usd - Y_usd| / total — high = skewed pool
- Active bin concentration (30%): active bin share of total liquidity

Regime classification:
- calm (0-33): proceed normally
- elevated (34-66): reduce exposure per maxExposurePct signal
- crisis (67-100): do not add liquidity

Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 25, 2026
Read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands: list-pools, assess-pool, assess-position, regime-history
Risk model: bin spread (30%) + reserve imbalance (40%) + active bin concentration (30%)
Regime: calm (0-33) / elevated (34-66) / crisis (67-100)
Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
@whoabuddy
Copy link
Copy Markdown
Contributor

Hey @locallaunchsc-cloud is this work intended for the Bitflow Skills Pay the Bills competition?

If so it needs to be submitted at this repo otherwise it wouldn't be eligible for credit:
https://github.com/BitflowFinance/bff-skills

Let me know, happy to continue the review process if it's unrelated!

sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 26, 2026
Adds read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands:
- list-pools: list all active HODLMM pools
- assess-pool: compute volatility score (0-100) and regime classification
- assess-position: evaluate LP position drift and concentration risk
- regime-history: scan all pools sorted by risk level

Risk model weights three signals:
- Bin spread (30%): fraction of bins with liquidity — low = risky
- Reserve imbalance (40%): |X_usd - Y_usd| / total — high = skewed pool
- Active bin concentration (30%): active bin share of total liquidity

Regime classification:
- calm (0-33): proceed normally
- elevated (34-66): reduce exposure per maxExposurePct signal
- crisis (67-100): do not add liquidity

Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
sonic-mast pushed a commit to sonic-mast/skills that referenced this pull request Mar 26, 2026
Read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands: list-pools, assess-pool, assess-position, regime-history
Risk model: bin spread (30%) + reserve imbalance (40%) + active bin concentration (30%)
Regime: calm (0-33) / elevated (34-66) / crisis (67-100)
Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
@locallaunchsc-cloud
Copy link
Copy Markdown
Author

@whoabuddy Yes, this is intended for the Bitflow Skills Pay the Bills competition. I'll submit it to the BitflowFinance/bff-skills repo as well. Thanks for the heads up!

@arc0btc I've addressed all the review feedback:

  • [blocking] Empty bins crash — Added a guard that throws an error when nonEmptyBins is empty, preventing the Math.min(...[]) / Math.max(...[]) Infinity/NaN issue.
  • [blocking] regime-history stub — Renamed to regime-snapshot, removed --samples entirely, and updated SKILL.md to reflect single-point behavior with a note about using an external time-series store for trend analysis.
  • [suggestion] driftScore / nearestOffset mismatch — Now exposing both nearestPositionBinOffset and avgBinOffset in the output so callers can see what's driving the score. SKILL.md documents that driftScore derives from avgBinOffset.
  • [nit] SKILL.md typo — Fixed "safeTo AddLiquidity""safeToAddLiquidity".
  • Code quality — Added comments explaining the 40/30/30 weight rationale for spread/imbalance/concentration.

Ready for re-review when you get a chance.

1 similar comment
@locallaunchsc-cloud
Copy link
Copy Markdown
Author

@whoabuddy Yes, this is intended for the Bitflow Skills Pay the Bills competition. I'll submit it to the BitflowFinance/bff-skills repo as well. Thanks for the heads up!

@arc0btc I've addressed all the review feedback:

  • [blocking] Empty bins crash — Added a guard that throws an error when nonEmptyBins is empty, preventing the Math.min(...[]) / Math.max(...[]) Infinity/NaN issue.
  • [blocking] regime-history stub — Renamed to regime-snapshot, removed --samples entirely, and updated SKILL.md to reflect single-point behavior with a note about using an external time-series store for trend analysis.
  • [suggestion] driftScore / nearestOffset mismatch — Now exposing both nearestPositionBinOffset and avgBinOffset in the output so callers can see what's driving the score. SKILL.md documents that driftScore derives from avgBinOffset.
  • [nit] SKILL.md typo — Fixed "safeTo AddLiquidity""safeToAddLiquidity".
  • Code quality — Added comments explaining the 40/30/30 weight rationale for spread/imbalance/concentration.

Ready for re-review when you get a chance.

@whoabuddy
Copy link
Copy Markdown
Contributor

Thanks for the submission! This has been superseded by #251 which incorporates the winning version from the BFF Skills Competition. Appreciate the work that went into this — it helped shape the final result. Closing in favor of #251.

@whoabuddy whoabuddy closed this Mar 28, 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.

3 participants