Skip to content

Structured JSON-LD reason on monthly pool retirements (#101 Phase A)#138

Open
brawlaphant wants to merge 1 commit into
regen-network:mainfrom
brawlaphant:feature/101-pool-structured-retirement-reason
Open

Structured JSON-LD reason on monthly pool retirements (#101 Phase A)#138
brawlaphant wants to merge 1 commit into
regen-network:mainfrom
brawlaphant:feature/101-pool-structured-retirement-reason

Conversation

@brawlaphant

Copy link
Copy Markdown
Contributor

Closes the pool-path gap in #101 Phase A.

Problem

buildRetirementReason (shipped in commit d3c4e80) is wired into:

  • retirement.ts (MCP tool path) ✅
  • retire-subscriber.ts (per-subscriber retirements) ✅
  • pool.ts (monthly pool runs) ❌ — still uses the plain string \"Monthly pool retirement — Regen Compute\"

Pool runs are where the on-chain volume happens — every subscriber's monthly contribution flows through MsgBuyDirect there. The plain-text reason gives indexers, the KOI semantic layer, and the eventual CLAMS CosmWasm contract no machine-readable context.

What this PR does

pool.ts now calls buildRetirementReason(...) with:

  • source: \"subscription\"
  • period: "YYYY-MM" derived from poolRun.run_date
  • note: human-readable "covering N subscriber(s)" descriptor

Backward-compatible: older consumers see a valid string (the JSON serialization).

Test

it(\"uses structured JSON-LD retirement reason on chain (#101 Phase A)\", async () => {
  await executePoolRun({ dryRun: false });
  const buyMsg = vi.mocked(signAndBroadcast).mock.calls[0][0][0];
  const parsed = JSON.parse(buyMsg.value.orders[0].retirementReason);
  expect(parsed[\"@context\"]).toBe(\"https://schema.regen.network/v1\");
  expect(parsed.type).toBe(\"ComputeFootprintRetirement\");
  expect(parsed.source).toBe(\"subscription\");
  expect(parsed.period).toMatch(/^\\d{4}-\\d{2}$/);
  expect(parsed.note).toMatch(/\\d+ subscribers?/);
});

Full suite: 50/50 passing (49 prior + 1 new).

Test plan

  • npm run typecheck — clean
  • npm test — 50/50 passing
  • npm run build — clean
  • Reviewer (or @glandua): confirm source: \"subscription\" is the intended literal for ADR-004 / CLAMS alignment. The other call sites use \"mcp_tool\" or \"subscription\"; pool runs are subscription-driven so I went with the latter.

Out of scope

  • The subscriberId field on StructuredReasonOptions is declared in retirement-reason.ts but buildRetirementReason() doesn't actually serialize it. Worth fixing in its own micro-PR if you want — pool runs cover many subscribers so it doesn't apply here, but it does for retire-subscriber.ts.
  • Phase B (formalizing COMPUTE_FOOTPRINT as an ADR-004 ClaimType) — that work lives in regen-data-standards, not here.

Refs: #101 Phase A

🤖 Generated with Claude Code

…tirements

Closes the pool-path gap in regen-network#101 Phase A. The buildRetirementReason
helper (commit d3c4e80) was wired into:
  - retirement.ts (MCP tool path)         ✅
  - retire-subscriber.ts (per-subscriber) ✅
  - pool.ts (monthly pool runs)           ❌ — still using plain string

Pool runs are the on-chain volume — every subscriber's monthly contribution
flows through MsgBuyDirect there. The plain-text reason
"Monthly pool retirement — Regen Compute" provides no machine-readable
context for indexers, the KOI semantic layer, or the eventual CLAMS
CosmWasm contract.

Now uses buildRetirementReason() with:
  - source: "subscription"
  - period: YYYY-MM derived from poolRun.run_date
  - note:   human-readable "covering N subscriber(s)" descriptor

Backward compatible: older consumers see a valid string (the JSON
serialization of the structured object).

Test: new pool.test.ts case "uses structured JSON-LD retirement reason
on chain (regen-network#101 Phase A)" captures the broadcast msg, parses
retirementReason as JSON, and asserts the @context, type, source,
period, and note fields.

Full suite: 50/50 passing (49 prior + 1 new).

Refs: regen-network#101 (Phase A pool-path gap)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces structured JSON-LD retirement reasons for on-chain transactions, replacing the previous plain text format. It includes a new test case to verify the JSON-LD structure and metadata. Feedback suggests moving the construction of the retirement reason outside the loop to avoid redundant calculations, as the inputs are constant for the entire pool run.

Comment thread src/services/pool.ts
Comment on lines +382 to +387
const period = poolRun.run_date.slice(0, 7); // YYYY-MM
const poolRetirementReason = buildRetirementReason({
note: `Monthly pool retirement covering ${subscribers.length} subscriber${subscribers.length === 1 ? "" : "s"}`,
period,
source: "subscription",
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The structured retirement reason is being recalculated and stringified inside the batch loop. Since the inputs (poolRun.run_date, subscribers.length, and the literal source) are constant for the entire pool run, this calculation should be moved outside the for loop (before line 279) to avoid redundant work and improve efficiency.

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