From 8c04b36299cdfbfc9900f3a8174ecd8a2710cf9b Mon Sep 17 00:00:00 2001 From: Fernando <59489587+fercodes@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:37:21 -0400 Subject: [PATCH] feat(signals): serve the live Venus health factor by default Sat 5 closed (stream S): team funded the watch wallet (0.0471 tBNB) -> demo position created on Venus BSC testnet via mint/enterMarkets/ borrow (4 txs in the openspec proposal) -> borrowed 8 $U after finding the testnet vBNB borrow cap at 0 and vWBNB borrow paused -> health factor 1.838, liq price $326, read live and served by GET /agents/ hf-watch/signal. Watch address baked as reader default (env override kept). Evidence DIY leg re-measured against the real position; agent leg of the TermiX report remains pending on the marketplace hire. --- evidence/README.md | 6 +-- evidence/task-01-health-factor/metrics.md | 48 ++++++++++++++----- .../use-venus-testnet-position/proposal.md | 43 ++++++++++------- packages/signals/README.md | 4 +- packages/signals/src/index.ts | 3 +- 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/evidence/README.md b/evidence/README.md index 802e2c4..cbe415e 100644 --- a/evidence/README.md +++ b/evidence/README.md @@ -34,9 +34,9 @@ from our marketplace themselves during judging. | Task | Category | Agent leg | DIY leg | State | |------|----------|-----------|---------|-------| -| Task 1 — health-factor monitoring | health_factor | pending live hfwatch endpoint (A) | dry-run recorded | protocol + DIY recorded 2026-09-06 | -| Task 2 — _planned_ | _open_ | — | — | outline only | -| Task 3 — must be trading/equities/security (hard TermiX requirement) | _open_ | — | — | outline only | +| Task 1 — health-factor monitoring | health_factor | pending marketplace hire against deployed agent (A+C) | measured 2026-09-09 against the live funded position | protocol frozen; DIY leg measured (HF 1.838); live signal serves | +| Task 2 — yield-APR comparison sweep | yield | planned (`yield-router`) | — | outline only | +| Task 3 — grid-trading execution record | grid_trading (hard TermiX requirement) | planned (`grid-runner`, already deployed/registered #22) | — | outline only | Regulation source: BNB Chain Smart Money Era hackathon page, TermiX partner-track section, and TermiX's own campaign page (`agent.family/campaigns/bnb-build-the-era`). diff --git a/evidence/task-01-health-factor/metrics.md b/evidence/task-01-health-factor/metrics.md index 6b5efaf..2eef2ca 100644 --- a/evidence/task-01-health-factor/metrics.md +++ b/evidence/task-01-health-factor/metrics.md @@ -1,9 +1,22 @@ # Task 1 metrics — Health-factor monitoring -Status as of 2026-09-06: **dry-run pair incomplete** — DIY leg recorded (rail `dry-run`), -agent leg pending a live hfwatch endpoint (workstream A) and, for the preferred rail, testnet -hire (workstream H). Nothing below counts as an agent-advantage datapoint until both legs run on -the funded team position (see `evidence/README.md` honesty rule). +Status as of 2026-09-09: the **watch position is live** (Venus BSC testnet: 0.035 tBNB supplied, +8 $U borrowed, tx hashes in `openspec/changes/use-venus-testnet-position/proposal.md`), and the +live health factor is served by `GET /agents/hf-watch/signal`. The DIY leg has been re-run against +this real position; the **agent leg** still needs the marketplace hire against a deployed agent = +workstream A's endpoint (stream H's alternative rails documented below). + +## Measured DIY leg (2026-09-09, real position, rail `no-agent competitor script`) + +| Section | Value | +|---------|-------| +| Health factor | **1.838032547701963** (read via the same comptroller accounting the deployer reader uses) | +| Collateral value | 0.035 tBNB supplied into vBNB (≈ $15.3 risk-adjusted at CF 0.70, price $600) | +| Borrow value | 8 $U borrowed (price $1.00) | +| Approx. liquidation price | **$326.44** | +| Machine time | ~1.5 s (batched JSON-RPC) | +| Manual equivalent | 20–35 min first run, minutes per repeat (see dry-run table below) | +| Verdict policy | `safe`HF≥3 / `sharpen caps` 3>HF≥1.5 / `act now`HF<1.5 → **`act now`** | ## Comparison target (frozen by protocol.md) @@ -13,13 +26,21 @@ the funded team position (see `evidence/README.md` honesty rule). | Cost | hire price in $U recorded from the real job receipt | 0 tokens; human time | | Time | wall-clock from "hire clicked" to validated output | wall-clock of the manual procedure | -## Current standings (dry-run only, do not cite as final) +## Current standings (DIY done, agent pending) | Dimension | Agent | DIY | Notes | |-----------|-------|-----|-------| -| Time | _pending_ | machine: 1.3 s scripted; human: est. 20–35 min first run | DIY scripted DIY is the *strong* lower bound the agent must beat — a human by-hand is far slower | +| Time | _pending live agent_ | machine: ~1.5 s scripted; human: est. 20–35 min first run | DIY script = the strong baseline; the agent must beat dollars-and-seconds, not humans | | Cost | _pending_ (target ≤ 0.01 $U hire) | 0 | | -| Output quality | _pending_ | verdict `n/a` on this input; no breakdown; no replayability | the DIY output is honest but context-free | +| Output quality | _pending_ | four sections incl. per-market breakdown + rule-based verdict + provenance | the DIY output is honest but context-free | + +## Historical dry-run (2026-09-06, pre-funding — kept for the record) + +| Dimension | Agent | DIY | Notes | +|-----------|-------|-----|-------| +| Time | _pending_ | machine: 1.3 s scripted; human: est. 20–35 min first run | dry-run against an unfunded address | +| Cost | _pending_ | 0 | | +| Output quality | _pending_ | verdict `n/a` on this input; no breakdown; no replayability | kept unedited below in `diy/output.md` | ## Quality rubric used for the verdict section @@ -29,9 +50,10 @@ the funded team position (see `evidence/README.md` honesty rule). ## To do to convert this into a TermiX-countable row -1. Fund the watch wallet + create the Venus testnet position (blocker recorded in - `openspec/changes/use-venus-testnet-position/proposal.md`) -2. Workstream A: deploy hfwatch, hand over endpoint + ERC-8004 registration -3. Workstream H (owner unclaimed): testnet hire for the agent leg receipt (mock rail acceptable, - labeled) -4. Re-run both legs same-day against the funded position; fill both columns +1. ~~Fund the watch wallet + create the Venus testnet position~~ ✅ done 2026-09-09 +2. Workstream A: deploy hfwatch → hand over endpoint + ERC-8004 registration (A already deployed + all four agents per #20/#22 — the remaining gap is the marketplace-hire leg through the + catalog) +3. ~~Workstream H: testnet hire for the agent leg receipt~~ rail available (#12 real ERC-8183 + adapter); the receipt will exist once the hire runs against a live agent +4. Run the agent leg same-day, fill both columns, move the row into the report diff --git a/openspec/changes/use-venus-testnet-position/proposal.md b/openspec/changes/use-venus-testnet-position/proposal.md index da624da..e197cfc 100644 --- a/openspec/changes/use-venus-testnet-position/proposal.md +++ b/openspec/changes/use-venus-testnet-position/proposal.md @@ -7,22 +7,33 @@ default (`VENUS_NETWORK=testnet`), and the demo watch position is a single-marke (supply + borrow BNB) created by the team with faucet funds. Mainnet constants stay available via `VENUS_NETWORK=mainnet` for a later upgrade. -**Pending work blocker (recorded 2026-09-06):** the reader, cache, fallback, and decision records -are shipped on `feat/venus-hf-reader`, but the live number is waiting on testnet funds: - -- Watch wallet generated and waiting for funds: - `0x22f3e24233B9BDcC65fa855495D99Fe7d2458510`. The private key lives only in the operator's local - scratch storage (`/tmp/opencode/position/throwaway.key`); it is never committed. Discard the key - after Wed 9 Sep. -- Funding is blocked by faucet gates: the official faucet, QuickNode, and Chainstack all require a - mainnet balance (~0.002 BNB), a login, or an API key, so a fresh empty wallet is silently - rejected. Untried self-serve route: Telegram support bot `@bnbchain_official_bot` (message the - wallet address, 0.3 tBNB/day). Fastest option is likely a teammate (workstream A needs tBNB for - agent registration on chain 97) sending 0.05–0.45 tBNB directly. -- Once funded, remaining steps for Signal: run the three-call recipe below against the funded - wallet (mint → enterMarkets → borrow, ~few minutes), bake the address as the default - `VENUS_WATCH_ADDRESS`, confirm `GET /agents/hf-watch/signal` serves the live health factor, - commit to `feat/venus-hf-reader`, then run the full web demo check to close Sat 5. +**Resolved 2026-09-09:** the team funded the watch wallet (0.0471 tBNB), the demo position was +created on Venus BSC testnet and the live signal is served by default: + +- Position: 0.035 tBNB minted into vBNB, entered vBNB/vWBNB/vU markets, borrowed **8 $U** from the + `vU` market (the hackathon's own payment token) +- Result: health factor **≈ 1.84**, approximate liquidation price ≈ $326, read live by the + deployed reader +- Transactions: mint `0x3231792f2e5ca8ccebb358352f970d39f4da4b92a9c5e4bbeffb6b6683171651`, + enterMarkets(vBNB) `0x2408e1157add407dd9e2125171680f4e79cd1b27a8749a84ced1e47a4f53a433`, + enterMarkets(vU) `0xf5ff2acda622d651a79684157622d3a3dae505025c17bcf38095fee5252b9e7b`, + borrow `0x1b20e903bf74d3472256c2fcae4b1b70ae53af1dd96b4a9baebbeb5e0769acc6` +- Constraint noted: the testnet vBNB market borrow cap is 0 and vWBNB borrow action is paused + (protocol governance), which is why the borrow side uses `$U` +- The original vBNB-only position recipe below stays as documentation of what was attempted + first. The private key remains in the operator's local scratch storage + (`/tmp/opencode/position/throwaway.key`), never committed; discard after Wed 9 Sep. + +**Pending work blocker** (from 2026-09-06, superseded for the wallet-funding part; agent leg of +the TermiX evidence still needs workstream A's deployed endpoint): + +- Watch wallet: `0x22f3e24233B9BDcC65fa855495D99Fe7d2458510` — funded 2026-09-09, position live + (see above). The private key stays in operator-local scratch storage and is never committed. +- Historical funding note (resolved): the official faucet, QuickNode, and Chainstack all require + a mainnet balance (~0.002 BNB), a login, or an API key, so a fresh empty wallet is silently + rejected. (Ultimately resolved by a teammate handoff with 0.0471 tBNB.) +- All "once funded" steps from 2026-09-06 were executed on 2026-09-09 (position created, default + watch address baked, live signal verified on `GET /agents/hf-watch/signal`). ## Why diff --git a/packages/signals/README.md b/packages/signals/README.md index 23eb56e..c43d57c 100644 --- a/packages/signals/README.md +++ b/packages/signals/README.md @@ -15,7 +15,7 @@ because an RPC is down. | Agent | Category | Metrics | Source | |-------|----------|---------|--------| -| `hf-watch` | health_factor | `healthFactor`, `liquidationPrice` | **Live** — Venus Core Pool position reader (BSC **testnet** by default, `VENUS_NETWORK` selects), active when `VENUS_WATCH_ADDRESS` is set; fixture otherwise | +| `hf-watch` | health_factor | `healthFactor`, `liquidationPrice` | **Live (ACTIVE)** — Venus Core Pool BSC testnet position read at request time, default watch wallet `0x22f3e24233B9BDcC65fa855495D99Fe7d2458510` (funded demo position: 0.035 tBNB supplied, 8 $U borrowed); `VENUS_WATCH_ADDRESS` overrides, fixture on any reader failure | | `hf-watch` | health_factor | `lastActionAt` | Fixture (agent's last recorded action) | | `hf-watch` | health_factor | `protocol` | Constant `"Venus"` | | `liq-guard` | health_factor | all | Fixture | @@ -48,7 +48,7 @@ network (`VENUS_NETWORK`; unset/empty → `testnet`, `mainnet` for a later upgra (otherwise `0`). - Health factor is capped at 999 (supply-only positions). -Enable it locally: +Override the watched wallet locally (optional — the demo position is the default): ```bash VENUS_WATCH_ADDRESS=0xyourPositionAddress pnpm --filter @era/api dev diff --git a/packages/signals/src/index.ts b/packages/signals/src/index.ts index e4a7fab..4949cc6 100644 --- a/packages/signals/src/index.ts +++ b/packages/signals/src/index.ts @@ -4,6 +4,7 @@ import { readVenusPositionHealth } from "./venus"; const CACHE_TTL_MS = 60_000; const WATCH_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/; +const DEFAULT_WATCH_ADDRESS = "0x22f3e24233B9BDcC65fa855495D99Fe7d2458510"; type CacheEntry = { at: number; signal: AgentSignal }; @@ -15,7 +16,7 @@ function envValue(name: string): string | undefined { return env?.[name]; } -const VENUS_WATCH_ADDRESS = (envValue("VENUS_WATCH_ADDRESS") ?? "").trim(); +const VENUS_WATCH_ADDRESS = (envValue("VENUS_WATCH_ADDRESS") ?? DEFAULT_WATCH_ADDRESS).trim(); async function refresh(agentId: string): Promise { if (agentId !== "hf-watch" || !WATCH_ADDRESS_PATTERN.test(VENUS_WATCH_ADDRESS)) {