feat: Add agentic-documentation skill#322
Conversation
- Agent registration with ERC-8004 identity - Performance tracking for games/strategies - Strategy publishing and discovery - Service offering for inference Part of aircade.xyz strategy marketplace vision
WalkthroughAdds an Agentic Documentation skill (machine-readable API patterns) and a new Strategy Marketplace skill implementing in-memory agent registry, performance tracking, publishing/discovery/purchase flows, service offerings, tests, scripts, and supporting docs and build configuration. Changes
Sequence DiagramsequenceDiagram
participant Agent1 as Agent 1<br/>(Creator)
participant Registry as Registry<br/>Module
participant Tracking as Tracking<br/>Module
participant Marketplace as Marketplace<br/>Module
participant Agent2 as Agent 2<br/>(Buyer)
Agent1->>Registry: registerAgent(config)
Registry-->>Agent1: RegisteredAgent
Agent1->>Tracking: trackPerformance(record)
Tracking-->>Agent1: ack
Note over Tracking: accumulate stats (wins, losses, roi)
Agent1->>Marketplace: publishStrategy(agentId, price, trackRecord)
Marketplace->>Tracking: getAgentStats(agentId)
Tracking-->>Marketplace: AgentStats
Marketplace->>Registry: getAgent(agentId)
Registry-->>Marketplace: RegisteredAgent
Note over Marketplace: validate certification (totalGames>=10, avgRoi>0, winRate>0.5)
Marketplace-->>Agent1: StrategyListing
Agent2->>Marketplace: discoverStrategies(query)
Marketplace-->>Agent2: StrategyListing[]
Agent2->>Marketplace: purchaseStrategy(strategyId, buyerAgentId)
Marketplace->>Registry: getAgent(buyerAgentId)
Registry-->>Marketplace: RegisteredAgent
Note over Marketplace: verify payment (stub) and generate accessId
Marketplace-->>Agent2: PurchaseResult (accessId, expiresAt)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 7 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (7 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR introduces two new skills: Key issues found:
Confidence Score: 1/5
|
| Filename | Overview |
|---|---|
| skills/strategy-marketplace/src/marketplace.ts | Critical issues in core marketplace logic: payment verification stub always returns true (line 505–515), certification win-rate calculation conflates totalGames with decisive games (line 225–227), and self-purchase is not prevented (line 134–166). These combine to create an exploit path where agents can arbitrarily grant themselves strategy access. The shallow-copy return from getAllListings is safe for current usage patterns. |
| skills/strategy-marketplace/src/registry.ts | Critical issues with agent identity: ERC8004_TOKEN_ID env var is used as-is without format validation or uniqueness checks (line 114–121), enabling arbitrary string injection and ID collisions across multiple registerAgent() calls. MARKETPLACE_CONTRACTS constant (line 10–19) is dead code and should be removed or documented with a TODO. __resetRegistryForTests is re-exported as public API. |
| skills/strategy-marketplace/src/index.ts | Barrel exports (export * from './registry', etc.) re-expose all internal test-reset helpers (__resetRegistryForTests, __resetTrackingForTests, __resetMarketplaceForTests) as part of the public package API. These should be explicitly excluded or moved to a separate test-utilities file. |
| skills/strategy-marketplace/src/tracking.ts | Performance tracking module is well-structured with solid input validation. Timestamp validation accepts any non-negative value (line 234–239), which is a defensive best practice rather than a concrete bug (current code does not use timestamps in win-rate calculations). __resetTrackingForTests is re-exported as public API. |
| skills/strategy-marketplace/src/types.ts | Type definitions are clear and well-documented. Note: StrategyListing.trackRecord lacks a draws field, which creates semantic ambiguity when calculating win rates (see marketplace.ts:225–227). |
Sequence Diagram
sequenceDiagram
participant Agent
participant Registry
participant Tracking
participant Marketplace
Agent->>Registry: registerAgent(config)
Note over Registry: validateRegistrationInput()<br/>generateAgentId() [env or random]<br/>getCurrentAgentAddress() [env or zero]
Registry-->>Agent: RegisteredAgent {id, address, ...}
Agent->>Tracking: trackPerformance(record)
Note over Tracking: validatePerformanceInput()<br/>verify agentId exists in Registry
Tracking-->>Agent: void
Agent->>Marketplace: publishStrategy(config)
Note over Marketplace: validatePublishStrategyInput()<br/>checkCertification(trackRecord)<br/>storeListing()
Marketplace-->>Agent: StrategyListing {id, certified, ...}
Agent->>Marketplace: discoverStrategies(query)
Marketplace-->>Agent: StrategyListing[]
Agent->>Marketplace: purchaseStrategy({strategyId, buyerAgentId})
Note over Marketplace: verifyPaymentStub() → always true ⚠️<br/>generateAccessId()
Marketplace-->>Agent: PurchaseResult {accessId, expiresAt}
Agent->>Marketplace: offerService(config)
Marketplace-->>Agent: ServiceOffering {id, active}
Last reviewed commit: 3240aeb
|
|
||
| async function checkCertification(trackRecord: StrategyListing['trackRecord']): Promise<boolean> { | ||
| // Certification criteria: | ||
| // - Minimum 10 games played | ||
| // - Positive average ROI | ||
| // - Win rate > 50% | ||
| if (trackRecord.totalGames < 10) return false; | ||
| if (trackRecord.avgRoi <= 0) return false; |
There was a problem hiding this comment.
Payment verification is permanently bypassed
verifyPaymentStub unconditionally returns true, meaning any agent can purchase any strategy at zero cost — no actual payment occurs. Since purchaseStrategy treats the stub result as authoritative (if (!paymentVerified) throw ...), the gate is completely ineffective as written.
If this ships to production before the real x402 settlement hook is wired in, every call to purchaseStrategy will silently succeed without transferring funds, allowing strategy access to be freely obtained.
At minimum the stub should throw or log a clear "NOT IMPLEMENTED" error to prevent accidental production deployment:
async function verifyPaymentStub(
buyerAgentId: string,
strategyId: string,
expectedPrice: number
): Promise<boolean> {
void buyerAgentId;
void strategyId;
void expectedPrice;
throw new Error(
'verifyPaymentStub: x402 settlement not implemented – do not deploy to production'
);
}Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/marketplace.ts
Line: 206-213
Comment:
**Payment verification is permanently bypassed**
`verifyPaymentStub` unconditionally returns `true`, meaning any agent can purchase any strategy at zero cost — no actual payment occurs. Since `purchaseStrategy` treats the stub result as authoritative (`if (!paymentVerified) throw ...`), the gate is completely ineffective as written.
If this ships to production before the real x402 settlement hook is wired in, every call to `purchaseStrategy` will silently succeed without transferring funds, allowing strategy access to be freely obtained.
At minimum the stub should throw or log a clear "NOT IMPLEMENTED" error to prevent accidental production deployment:
```typescript
async function verifyPaymentStub(
buyerAgentId: string,
strategyId: string,
expectedPrice: number
): Promise<boolean> {
void buyerAgentId;
void strategyId;
void expectedPrice;
throw new Error(
'verifyPaymentStub: x402 settlement not implemented – do not deploy to production'
);
}
```
How can I resolve this? If you propose a fix, please make it concise.| export async function listAgents(): Promise<RegisteredAgent[]> { | ||
| return getStoredAgents(); | ||
| } | ||
|
|
||
| /** | ||
| * Update agent capabilities | ||
| */ | ||
| export async function updateAgent( |
There was a problem hiding this comment.
Fixed env var causes agent-ID collision across multiple registrations
generateAgentId() reads ERC8004_TOKEN_ID once as a static value, so every registerAgent() call within the same process environment returns the same ID. Because storeAgent uses agents.set(agent.id, agent), a second call to registerAgent() silently overwrites the first agent's entry — breaking ERC-8004 identity isolation.
This is reproduced in the test file where multiple agents are registered sequentially. If ERC8004_TOKEN_ID is set in the test environment, all tests that call registerAgent would end up sharing one identity, causing getAgent() lookups to return the wrong agent and purchaseStrategy to resolve the wrong buyer.
The env var pattern only makes sense for a single-agent-per-process model, but even there the assignment should happen once at startup and never be re-used for subsequent registrations. Consider requiring the token ID to be passed explicitly as part of AgentRegistration when it is provided externally:
function generateAgentId(overrideTokenId?: string): string {
if (overrideTokenId) return overrideTokenId;
return `0x${randomBytes(32).toString('hex')}`;
}And pass config.tokenId (an optional field) into it from registerAgent, rather than reading a global env var on every invocation.
Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/registry.ts
Line: 77-84
Comment:
**Fixed env var causes agent-ID collision across multiple registrations**
`generateAgentId()` reads `ERC8004_TOKEN_ID` once as a static value, so every `registerAgent()` call within the same process environment returns the *same* ID. Because `storeAgent` uses `agents.set(agent.id, agent)`, a second call to `registerAgent()` silently overwrites the first agent's entry — breaking ERC-8004 identity isolation.
This is reproduced in the test file where multiple agents are registered sequentially. If `ERC8004_TOKEN_ID` is set in the test environment, all tests that call `registerAgent` would end up sharing one identity, causing `getAgent()` lookups to return the wrong agent and `purchaseStrategy` to resolve the wrong buyer.
The env var pattern only makes sense for a single-agent-per-process model, but even there the assignment should happen once at startup and never be re-used for subsequent registrations. Consider requiring the token ID to be passed explicitly as part of `AgentRegistration` when it is provided externally:
```typescript
function generateAgentId(overrideTokenId?: string): string {
if (overrideTokenId) return overrideTokenId;
return `0x${randomBytes(32).toString('hex')}`;
}
```
And pass `config.tokenId` (an optional field) into it from `registerAgent`, rather than reading a global env var on every invocation.
How can I resolve this? If you propose a fix, please make it concise.| registry: '0x...', | ||
| marketplace: '0x...' | ||
| } | ||
| }; | ||
|
|
||
| const SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/; | ||
| type RegistryState = { agents: Map<string, RegisteredAgent> }; | ||
|
|
||
| function getRegistryState(): RegistryState { | ||
| const globalState = globalThis as typeof globalThis & { |
There was a problem hiding this comment.
MARKETPLACE_CONTRACTS is declared but never referenced
The constant is defined with placeholder addresses for both SN_MAIN and SN_SEPOLIA, but no code in registry.ts (or anywhere else in this PR) reads from it. TypeScript's strict mode will not warn about unused const declarations, so this can silently remain dead code.
Either remove it until the contract-backed path is implemented, or add a // TODO: use in on-chain mint call comment so it doesn't accumulate as dead weight:
| registry: '0x...', | |
| marketplace: '0x...' | |
| } | |
| }; | |
| const SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/; | |
| type RegistryState = { agents: Map<string, RegisteredAgent> }; | |
| function getRegistryState(): RegistryState { | |
| const globalState = globalThis as typeof globalThis & { | |
| // TODO: use these when ERC-8004 mint is implemented | |
| const MARKETPLACE_CONTRACTS = { | |
| SN_MAIN: { | |
| registry: '0x...', // ERC-8004 registry | |
| marketplace: '0x...' | |
| }, | |
| SN_SEPOLIA: { | |
| registry: '0x...', | |
| marketplace: '0x...' | |
| } | |
| }; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/registry.ts
Line: 16-25
Comment:
**`MARKETPLACE_CONTRACTS` is declared but never referenced**
The constant is defined with placeholder addresses for both `SN_MAIN` and `SN_SEPOLIA`, but no code in `registry.ts` (or anywhere else in this PR) reads from it. TypeScript's `strict` mode will not warn about unused `const` declarations, so this can silently remain dead code.
Either remove it until the contract-backed path is implemented, or add a `// TODO: use in on-chain mint call` comment so it doesn't accumulate as dead weight:
```suggestion
// TODO: use these when ERC-8004 mint is implemented
const MARKETPLACE_CONTRACTS = {
SN_MAIN: {
registry: '0x...', // ERC-8004 registry
marketplace: '0x...'
},
SN_SEPOLIA: {
registry: '0x...',
marketplace: '0x...'
}
};
```
How can I resolve this? If you propose a fix, please make it concise.| export * from './types'; | ||
| export * from './registry'; | ||
| export * from './tracking'; |
There was a problem hiding this comment.
Internal test-reset helpers leak into the public API
export * from './registry', export * from './tracking', and export * from './marketplace' re-export __resetRegistryForTests, __resetTrackingForTests, and __resetMarketplaceForTests as part of the public package surface. Any downstream consumer of @aircade/strategy-marketplace will see and be able to call these wipe-all-state functions.
Explicitly exclude them from the barrel, or move them to a separate test-utilities file that is never re-exported:
export type { AgentRegistration, RegisteredAgent, /* ... */ } from './types';
export { registerAgent, getAgent, listAgents, updateAgent } from './registry';
export { trackPerformance, getAgentStats, getWinRate, getTopStrategies } from './tracking';
export { publishStrategy, discoverStrategies, getStrategy, purchaseStrategy, offerService, getAgentServices } from './marketplace';Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/index.ts
Line: 8-10
Comment:
**Internal test-reset helpers leak into the public API**
`export * from './registry'`, `export * from './tracking'`, and `export * from './marketplace'` re-export `__resetRegistryForTests`, `__resetTrackingForTests`, and `__resetMarketplaceForTests` as part of the public package surface. Any downstream consumer of `@aircade/strategy-marketplace` will see and be able to call these wipe-all-state functions.
Explicitly exclude them from the barrel, or move them to a separate test-utilities file that is never re-exported:
```typescript
export type { AgentRegistration, RegisteredAgent, /* ... */ } from './types';
export { registerAgent, getAgent, listAgents, updateAgent } from './registry';
export { trackPerformance, getAgentStats, getWinRate, getTopStrategies } from './tracking';
export { publishStrategy, discoverStrategies, getStrategy, purchaseStrategy, offerService, getAgentServices } from './marketplace';
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Actionable comments posted: 14
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/agentic-documentation/SKILL.md`:
- Around line 66-80: The documentation lists inconsistent category tokens: the
required field `category` table uses `auth` but the Categories section lists
`authentication`; pick one canonical token (e.g., either `auth` or
`authentication`) and make them consistent across the doc by updating the
`category` field row and the bullet list values (references: the `category`
field in the table and the Categories list items like
AUTH_TOKEN_EXPIRED/AUTH_INSUFFICIENT_PERMISSIONS); ensure all examples and enum
mentions use the chosen token consistently.
- Around line 135-246: Add a concrete starknet.js example to SKILL.md (e.g.,
under Pattern 3 or Pattern 4) that demonstrates using starknet.js primitives:
instantiate a Provider/Account, build and sign an invokeTransaction, send it
(account.execute or provider.sendTransaction), and poll for receipt
(provider.getTransactionReceipt), plus show expected request/response shapes;
ensure the snippet is labeled "starknet.js Example" and references the library
names (Provider, Account, invokeFunction/getTransactionReceipt) so readers can
find it quickly.
- Around line 1-11: SKILL.md is missing the required companion assets: create a
references/ directory containing deep-dive documentation topics that expand the
quick reference (e.g., API surface, error-code schemas, versioning signals) and
add a scripts/ directory with runnable examples in TypeScript or Python that
demonstrate usage of the agentic-documentation patterns; ensure the new
references content aligns with the metadata in SKILL.md (name/version/keywords)
and the scripts include at least one executable example and README-like comments
so CI and reviewers can validate them.
In `@skills/strategy-marketplace/package.json`:
- Line 10: The package.json test script currently calls Bun ("test": "bun test
./src/strategy-marketplace.test.ts") but Bun is not declared as a repo-level
requirement; update package.json to replace the Bun invocation by the
repo-supported test runner already in devDependencies (vitest) by changing the
"test" script to run vitest (e.g., "test": "vitest
./src/strategy-marketplace.test.ts" or equivalent CLI flags used across the
repo), ensuring the test runs under the declared Node/pnpm toolchain;
alternatively, if you intend to require Bun, add Bun to the repo-level
requirements (engines/CI/docs) and declare it accordingly—but prefer migrating
the "test" script to use the existing "vitest" devDependency.
In `@skills/strategy-marketplace/README.md`:
- Around line 33-37: The example call to purchaseStrategy is missing the
required buyerAgentId parameter which will cause runtime errors; update the
snippet that calls purchaseStrategy (involving discoverStrategies and the
strategies[0].id) to pass the buyerAgentId argument (e.g., buyerAgentId:
<your-agent-id>) along with strategyId so the call matches the current API
signature of purchaseStrategy.
In `@skills/strategy-marketplace/SKILL.md`:
- Around line 236-237: The checklist in SKILL.md still shows pending items for
api-spec.md, design-notes.md and the scripts registerAgent.ts,
publishStrategy.ts, trackPerformance.ts even though this PR adds those files;
update SKILL.md to mark those checklist items as completed (or remove them) so
the next-steps list reflects the current state, specifically edit the checklist
entries referencing api-spec.md, design-notes.md and the three script examples
to use checked boxes or remove the lines.
In `@skills/strategy-marketplace/src/marketplace.ts`:
- Around line 37-51: Replace free-form Error throws in marketplace APIs with a
typed MarketplaceError that includes a machine-readable code and a retryable
boolean; create a MarketplaceError class (e.g., class MarketplaceError extends
Error { code: string; retryable: boolean; constructor(code: string, message:
string, retryable = false) {...}}) and update throw sites such as
publishStrategy (agent not found), and the other similar error locations
referenced (the other validation/lookup failures in this file) to throw new
MarketplaceError('AGENT_NOT_FOUND', `Agent not found:
${validatedConfig.agentId}`, false) or appropriate codes/retry flags so
callers/agents can branch/retry reliably. Ensure existing catchers/logging
propagate or map MarketplaceError fields rather than relying on free-form
message parsing.
- Around line 238-250: The marketplace exposes mutable internal objects because
getAllListings and getAllOfferings return shallow-copied arrays with original
StrategyListing/ServiceOffering object references; update these accessors to
return deep-cloned objects (e.g., map each item to a clone) and ensure
storeListing (and any write-paths) also clone incoming objects before storing to
avoid external references mutating internal state; target the functions
getAllListings, getAllOfferings and storeListing (and analogous add/update
helpers) to implement clone-on-read and clone-on-write.
- Around line 398-408: The verifyPaymentStub function currently always returns
true which allows free purchases; change it to fail-closed by returning false
(or throwing a clear error) until a real payment verifier is implemented, update
the function verifyPaymentStub signature usage so purchase logic (e.g.,
purchaseStrategy) treats a false result as a failed payment and aborts the
purchase flow, and add a TODO comment referencing the real x402 settlement hook
to remind future wiring of the real verifier.
In `@skills/strategy-marketplace/src/strategy-marketplace.test.ts`:
- Around line 136-143: The test uses a bare rejects.toThrow() which is too
broad; update the assertions in the failing test cases (the test calling
registerAgent(...) and the other similar tests) to assert a specific, stable
error contract from the validation layer—e.g.,
expect(registerAgent(...)).rejects.toThrowError(/specific validation message/)
or expect(...).rejects.toMatchObject({ code: 'INVALID_PAYLOAD' }) or check a
boolean property like error.retryable === false; locate the calls to
registerAgent and other tested functions in this file (the it('rejects invalid
registration and performance payloads') block and the other blocks at the
referenced ranges) and replace bare toThrow() with explicit message or
object-matching assertions that reflect the validator's error shape.
- Around line 84-113: The test uses the same agent for publishing and buying
which hides cross-agent behavior; update the test around
registerAgent/publishStrategy/purchaseStrategy so you create a second agent
(e.g., buyerAgent via registerAgent) and call purchaseStrategy with
buyerAgent.id instead of agent.id; change assertions if needed to reference
buyerAgent where purchase ownership or access is validated and ensure
discover/publish still use the original agent variable and
publishStrategy/listing remain unchanged.
In `@skills/strategy-marketplace/src/tracking.ts`:
- Around line 51-67: getAgentStats currently treats any unknown agentId as an
existing agent by returning zeroed stats after calling getPerformanceHistory;
instead, first validate the agent exists (e.g., call your project’s agent lookup
such as getAgentById or fetchAgent) inside getAgentStats before returning empty
stats, and only return zeroed stats when the agent is confirmed to exist but has
no performance history; update callers like getWinRate will then correctly
surface errors for nonexistent agents rather than misleading zeros.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 298337cf-9752-4017-81d9-f2c634abf18b
📒 Files selected for processing (17)
skills/agentic-documentation/SKILL.mdskills/strategy-marketplace/README.mdskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/package.jsonskills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/references/certification-criteria.mdskills/strategy-marketplace/references/design-notes.mdskills/strategy-marketplace/scripts/publishStrategy.tsskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/scripts/trackPerformance.tsskills/strategy-marketplace/src/index.tsskills/strategy-marketplace/src/marketplace.tsskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/src/strategy-marketplace.test.tsskills/strategy-marketplace/src/tracking.tsskills/strategy-marketplace/src/types.tsskills/strategy-marketplace/tsconfig.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
skills/**/{SKILL.md,references/**,scripts/**}
📄 CodeRabbit inference engine (AGENT.md)
Documentation for skills must include quick reference in SKILL.md, deep-dive topics in
references/subdirectory, and runnable examples inscripts/subdirectory
Files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/references/design-notes.mdskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/references/certification-criteria.mdskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/scripts/trackPerformance.tsskills/strategy-marketplace/scripts/publishStrategy.tsskills/agentic-documentation/SKILL.md
skills/**/SKILL.md
📄 CodeRabbit inference engine (AGENT.md)
Skill definitions must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Files:
skills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
skills/*/SKILL.md
📄 CodeRabbit inference engine (CLAUDE.md)
skills/*/SKILL.md: Skills must include YAML frontmatter with fields:name,description,keywords,allowed-tools,user-invocable
Skill names must be lowercase with hyphens only, 1-64 characters
Skills must include code examples with starknet.js patterns
Skills must list error codes with recovery steps
Files:
skills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
🧠 Learnings (41)
📓 Common learnings
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: Consult the `references/agentskills/` directory for AgentSkills specifications covering integration patterns, skill format, and skill definitions
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to **/skills/*/SKILL.md : Skills must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable metadata in a SKILL.md file
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to skills/**/SKILL.md : Skill definitions must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/*/SKILL.md : Skill files must follow AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:53:48.727Z
Learning: Applies to skills/**/SKILL.md : Include code examples with starknet.js patterns in skill documentation
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Consult the `references/` directory (especially `references/starknet-docs/` and `references/agentskills/`) as the authoritative knowledge base before writing skills, contracts, or integrations
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Always consult the `references/` directory (Starknet documentation and AgentSkills specs) before writing skills, contracts, or integrations
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/**/{SKILL.md,references/**/*,scripts/**/*.{ts,py}} : Skills must include SKILL.md documentation, reference documentation in references/ subdirectory, and runnable TypeScript/Python examples in scripts/ subdirectory
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Agent-safe operations include reading/analyzing files, writing TypeScript/Cairo source, tests, skills and docs, running builds/tests, and creating new skills following established patterns
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Consult the `references/` directory (especially `references/starknet-docs/` and `references/agentskills/`) as the authoritative knowledge base before writing skills, contracts, or integrations
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/references/design-notes.mdskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/README.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Always consult the `references/` directory (Starknet documentation and AgentSkills specs) before writing skills, contracts, or integrations
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/references/design-notes.mdskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/**/*.md : Reference avnu SDK for all DeFi operations in skills
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/SKILL.md
📚 Learning: 2026-02-21T11:12:59.733Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: Consult the `references/agentskills/` directory for AgentSkills specifications covering integration patterns, skill format, and skill definitions
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/references/design-notes.mdskills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/**/{SKILL.md,references/**/*,scripts/**/*.{ts,py}} : Skills must include SKILL.md documentation, reference documentation in references/ subdirectory, and runnable TypeScript/Python examples in scripts/ subdirectory
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-24T20:27:50.560Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-02-24T20:27:50.560Z
Learning: PR description must include 'Spec impact' with either 'none' or concrete compatibility/migration notes for changes in contracts/session-account/**, packages/**, docs/**, or .github/workflows/**
Applied to files:
skills/strategy-marketplace/references/api-spec.md
📚 Learning: 2026-02-16T23:56:29.389Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T23:56:29.389Z
Learning: Applies to **/packages/starknet-mcp-server/tools/**/*.{ts,tsx,js} : DeFi integrations should use the avnu aggregator SDK and follow the avnu Skill patterns for swaps, DCA, staking, gasless, and gasfree implementations
Applied to files:
skills/strategy-marketplace/references/api-spec.mdskills/strategy-marketplace/package.jsonskills/strategy-marketplace/src/types.tsskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/src/index.ts
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Agent-safe operations include reading/analyzing files, writing TypeScript/Cairo source, tests, skills and docs, running builds/tests, and creating new skills following established patterns
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/scripts/trackPerformance.tsskills/strategy-marketplace/scripts/publishStrategy.tsskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-17T05:40:36.508Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T05:40:36.508Z
Learning: Applies to packages/*/package.json : Use ESM-only configuration with `"type": "module"` in package.json for TypeScript packages
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/**/*.{ts,tsx} : TypeScript/JavaScript packages must use proper type definitions and follow the extension patterns for Daydreams and Lucid Agents integrations
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/types.ts
📚 Learning: 2026-02-24T20:25:10.945Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-24T20:25:10.945Z
Learning: Applies to packages/*/tsup.config.{ts,js} : Build TypeScript packages with tsup targeting ESM format with `.d.ts` generation
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-17T04:43:12.245Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T04:43:12.245Z
Learning: Applies to packages/*/tsup.config.ts : Build TypeScript packages with tsup targeting ESM format with `.d.ts` generation
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/create-starknet-agent/**/*.{ts,tsx,js} : CLI scaffolding tool (`create-starknet-agent`) must provide E2E onboarding examples for agent setup on Starknet
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/src/strategy-marketplace.test.tsskills/strategy-marketplace/scripts/trackPerformance.tsskills/strategy-marketplace/scripts/publishStrategy.ts
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to **/*.{ts,tsx,js}@(!(node_modules)/**) : Use `starknet.js` v6 as the standard library for Starknet blockchain interactions in TypeScript/JavaScript code
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-16T23:56:29.389Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T23:56:29.389Z
Learning: Applies to packages/**/*.ts : Starknet integration must use avnu aggregator for DeFi operations including swaps, quotes, staking, and DCA patterns
Applied to files:
skills/strategy-marketplace/package.json
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/starknet-a2a/**/*.{ts,tsx,js} : Agent-to-Agent communication must implement the A2A protocol for agent discovery and interoperability
Applied to files:
skills/strategy-marketplace/package.jsonskills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/types.tsskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/README.md
📚 Learning: 2026-02-16T20:43:28.133Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:43:28.133Z
Learning: Applies to packages/starknet-mcp-server/**/*.ts : MCP server implementations must expose tools for Starknet access (balance queries, transfers, swaps, contract calls, fee estimation) compatible with any MCP-compatible agent framework
Applied to files:
skills/strategy-marketplace/package.json
📚 Learning: 2026-02-21T11:12:59.733Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: Applies to packages/**/*.ts : Lucid Agents integration must implement the Extension interface with WalletConnector using lucid-agents/types
Applied to files:
skills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/types.tsskills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T05:58:24.900Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T05:58:24.900Z
Learning: CLI scaffolding tool (`create-starknet-agent`) should provide E2E onboarding examples and cross-chain agent registration capabilities
Applied to files:
skills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/SKILL.mdskills/strategy-marketplace/README.mdskills/strategy-marketplace/scripts/publishStrategy.ts
📚 Learning: 2026-02-17T05:40:36.508Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T05:40:36.508Z
Learning: Example projects must demonstrate end-to-end onboarding flows including cross-chain agent registration and wallet creation
Applied to files:
skills/strategy-marketplace/scripts/registerAgent.tsskills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-17T04:43:12.245Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T04:43:12.245Z
Learning: Applies to packages/*/tsup.config.ts : Build TypeScript with tsup targeting ESM format with `.d.ts` generation
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-17T05:40:36.508Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: website/CLAUDE.md:0-0
Timestamp: 2026-02-17T05:40:36.508Z
Learning: Configure path aliases in tsconfig.json: `@/`* → ./app/*, `@/lib/`* → ./lib/*
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-15T18:44:13.849Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-15T18:44:13.849Z
Learning: Configuration files (Scarb.toml, tsconfig.json, .prettierrc) must be committed to version control and reviewed for dependency/compatibility changes
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-24T20:25:10.945Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-24T20:25:10.945Z
Learning: Applies to packages/*/package.json : TypeScript packages must use ESM-only format with `"type": "module"` in package.json
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-17T05:40:36.508Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T05:40:36.508Z
Learning: Applies to packages/*/package.json : TypeScript packages must be ESM-only with `"type": "module"` in package.json
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-15T17:03:40.212Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: website/CLAUDE.md:0-0
Timestamp: 2026-02-15T17:03:40.212Z
Learning: Applies to website/app/data/**/*.{ts,tsx} : Store static data with TypeScript types in `app/data/`
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-21T17:48:36.613Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: website/CLAUDE.md:0-0
Timestamp: 2026-02-21T17:48:36.613Z
Learning: Applies to website/**/next.config.ts : Configure Next.js with MDX support in `next.config.ts` for proper compilation and processing of MDX files
Applied to files:
skills/strategy-marketplace/tsconfig.json
📚 Learning: 2026-02-16T20:43:37.314Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:43:37.314Z
Learning: Use ERC-8004 (Cairo implementation) for on-chain agent identity, reputation, and validation registry functionality
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to contracts/**/*{identity,reputation,validation}*.{cairo,test.*} : Implement ERC-8004 identity, reputation, and validation registries with production-ready unit and E2E testing coverage
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T20:44:56.184Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:44:56.184Z
Learning: Applies to **/contracts/agent-account/**/*.{test,spec}.{ts,tsx,cairo} : Agent Account contract must be tested with at least 110 unit tests and E2E tests before production deployment
Applied to files:
skills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/src/strategy-marketplace.test.ts
📚 Learning: 2026-02-17T00:53:48.727Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:53:48.727Z
Learning: Applies to skills/**/SKILL.md : Include code examples with starknet.js patterns in skill documentation
Applied to files:
skills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to skills/**/{SKILL.md,references/**,scripts/**} : Documentation for skills must include quick reference in SKILL.md, deep-dive topics in `references/` subdirectory, and runnable examples in `scripts/` subdirectory
Applied to files:
skills/strategy-marketplace/SKILL.mdskills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-17T00:53:48.727Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:53:48.727Z
Learning: Applies to skills/**/SKILL.md : Skills must include code examples with starknet.js patterns
Applied to files:
skills/strategy-marketplace/SKILL.md
📚 Learning: 2026-02-21T11:12:59.733Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: A2A (Agent-to-Agent) implementation must support agent discovery and communication using the A2A protocol for Starknet agents
Applied to files:
skills/strategy-marketplace/README.md
📚 Learning: 2026-02-16T20:44:56.184Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:44:56.184Z
Learning: Applies to contracts/**/*.test.cairo : All smart contracts must include comprehensive unit tests (110+ tests for Agent Account) and E2E tests (47+ tests) before deployment
Applied to files:
skills/strategy-marketplace/src/strategy-marketplace.test.ts
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to **/skills/*/SKILL.md : Skills must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable metadata in a SKILL.md file
Applied to files:
skills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/*/SKILL.md : Skill files must follow AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Applied to files:
skills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to skills/**/SKILL.md : Skill definitions must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Applied to files:
skills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-24T20:25:10.945Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-24T20:25:10.945Z
Learning: Applies to skills/*/SKILL.md : Skills must include YAML frontmatter with fields: `name`, `description`, `keywords`, `allowed-tools`, `user-invocable`
Applied to files:
skills/agentic-documentation/SKILL.md
📚 Learning: 2026-02-21T11:23:54.628Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-21T11:23:54.628Z
Learning: Applies to skills/**/SKILL.md : List error codes with recovery steps in skill documentation
Applied to files:
skills/agentic-documentation/SKILL.md
🔇 Additional comments (13)
skills/strategy-marketplace/references/certification-criteria.md (1)
1-10: Certification criteria documentation is aligned with implementation.The documented thresholds and
certifiedsemantics matchcheckCertificationandpublishStrategybehavior.skills/strategy-marketplace/tsconfig.json (1)
1-17: TS project configuration looks consistent for the package build.Strict typing, declaration emit, and module settings are coherent with the package’s ESM output.
skills/strategy-marketplace/references/api-spec.md (1)
1-20: API notes are clear and correctly scoped.The transport and future parity guidance are explicit and aligned with the current in-process implementation.
skills/strategy-marketplace/src/types.ts (1)
1-98: Type surface is clear and well-structured.Interfaces are consistent across agent, tracking, strategy, discovery, and purchase flows.
skills/strategy-marketplace/src/index.ts (1)
8-11: Barrel exports are clean and consistentRe-export surface is straightforward and matches the intended public API split across types/registry/tracking/marketplace.
skills/strategy-marketplace/references/design-notes.md (1)
5-14: Design notes align with current implementationThe storage model and migration direction are concise and consistent with the in-memory module behavior.
skills/strategy-marketplace/scripts/registerAgent.ts (1)
1-18: Good runnable registration exampleThe script is concise, exercises the public API correctly, and includes proper failure handling.
skills/strategy-marketplace/scripts/trackPerformance.ts (1)
1-27: Tracking flow example looks solidThis script provides a clean onboarding path for register + track operations with valid payload shape.
skills/strategy-marketplace/scripts/publishStrategy.ts (1)
1-37: Publish strategy example is well-formedFlow and payload shape are coherent with the marketplace API and useful for quick validation.
skills/strategy-marketplace/src/strategy-marketplace.test.ts (4)
14-18: Strong test isolation via full state reset.Resetting registry, tracking, and marketplace in
beforeEachkeeps test cases independent and deterministic.
20-37: Registration/update lifecycle coverage looks solid.This block validates create → list → get → update with concrete assertions on persisted fields.
39-82: Performance aggregation scenario is well exercised.Good coverage of sequential tracking plus aggregate stats and top-strategy ranking checks.
114-134: Service offering/listing assertions are clear and sufficient.This validates both successful creation and discoverability through agent-scoped listing.
| --- | ||
| name: agentic-documentation | ||
| description: Write API documentation that AI agents can parse and use. Structured error codes, versioning signals, machine-readable quick references, and headless API patterns. Essential for building agent-friendly tools and services. | ||
| license: MIT | ||
| metadata: {"author":"Zaia (spiritclawd)","version":"1.0.0","org":"keep-starknet-strange"} | ||
| keywords: [documentation, api, agents, error-codes, versioning, machine-readable, headless, automation] | ||
| allowed-tools: [Bash, Read, Write, Glob, Grep, Task] | ||
| user-invocable: true | ||
| --- | ||
|
|
||
| # Agentic Documentation Skill |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== all files under skills/agentic-documentation/ =="
fd -H '' skills/agentic-documentation/ 2>/dev/null || echo "(directory or files not found)"
echo ""
echo "== checking references subdirectory =="
ls -la skills/agentic-documentation/references/ 2>/dev/null || echo "(references/ does not exist)"
echo ""
echo "== checking scripts subdirectory =="
ls -la skills/agentic-documentation/scripts/ 2>/dev/null || echo "(scripts/ does not exist)"
echo ""
echo "== ts/py files in scripts =="
find skills/agentic-documentation/scripts/ -type f \( -name "*.ts" -o -name "*.py" \) 2>/dev/null || echo "(no scripts found)"Repository: keep-starknet-strange/starknet-agentic
Length of output: 352
Skill package structure incomplete—references/ and scripts/ subdirectories required.
This skill defines the YAML frontmatter correctly in SKILL.md, but the PR is missing required companion assets:
references/subdirectory with deep-dive documentationscripts/subdirectory with runnable TypeScript or Python examples
Per established skill conventions, all skills must include these three components: quick reference (SKILL.md), deep-dive topics (references/), and runnable examples (scripts/).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/agentic-documentation/SKILL.md` around lines 1 - 11, SKILL.md is
missing the required companion assets: create a references/ directory containing
deep-dive documentation topics that expand the quick reference (e.g., API
surface, error-code schemas, versioning signals) and add a scripts/ directory
with runnable examples in TypeScript or Python that demonstrate usage of the
agentic-documentation patterns; ensure the new references content aligns with
the metadata in SKILL.md (name/version/keywords) and the scripts include at
least one executable example and README-like comments so CI and reviewers can
validate them.
| ### Required Fields | ||
|
|
||
| | Field | Type | Purpose | | ||
| |-------|------|---------| | ||
| | `code` | string | SCREAMING_SNAKE_CASE identifier | | ||
| | `category` | string | auth, validation, throttling, resource, state | | ||
| | `message` | string | Human-readable (for logs) | | ||
| | `retryable` | boolean | Can agent retry? | | ||
| | `request_id` | string | Debugging trace | | ||
|
|
||
| ### Categories | ||
|
|
||
| - **authentication** - AUTH_TOKEN_EXPIRED, AUTH_INSUFFICIENT_PERMISSIONS | ||
| - **validation** - VALIDATION_FAILED, VALIDATION_FIELD_MISSING | ||
| - **throttling** - RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED | ||
| - **resource** - RESOURCE_NOT_FOUND, RESOURCE_LOCKED | ||
| - **state** - INVALID_STATE_TRANSITION, PRECONDITION_FAILED |
There was a problem hiding this comment.
Error codes are listed, but recovery steps are missing.
For agent execution safety, each code should include machine-readable recovery guidance (e.g., retry strategy, operator action, terminal/fatal flag).
As per coding guidelines: "Skills must list error codes with recovery steps".
| | Field | Type | Purpose | | ||
| |-------|------|---------| | ||
| | `code` | string | SCREAMING_SNAKE_CASE identifier | | ||
| | `category` | string | auth, validation, throttling, resource, state | | ||
| | `message` | string | Human-readable (for logs) | | ||
| | `retryable` | boolean | Can agent retry? | | ||
| | `request_id` | string | Debugging trace | | ||
|
|
||
| ### Categories | ||
|
|
||
| - **authentication** - AUTH_TOKEN_EXPIRED, AUTH_INSUFFICIENT_PERMISSIONS | ||
| - **validation** - VALIDATION_FAILED, VALIDATION_FIELD_MISSING | ||
| - **throttling** - RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED | ||
| - **resource** - RESOURCE_NOT_FOUND, RESOURCE_LOCKED | ||
| - **state** - INVALID_STATE_TRANSITION, PRECONDITION_FAILED |
There was a problem hiding this comment.
category enum is inconsistent (auth vs authentication).
The required field table defines auth, but the category list uses authentication. Keep one canonical token set to avoid parser drift.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/agentic-documentation/SKILL.md` around lines 66 - 80, The
documentation lists inconsistent category tokens: the required field `category`
table uses `auth` but the Categories section lists `authentication`; pick one
canonical token (e.g., either `auth` or `authentication`) and make them
consistent across the doc by updating the `category` field row and the bullet
list values (references: the `category` field in the table and the Categories
list items like AUTH_TOKEN_EXPIRED/AUTH_INSUFFICIENT_PERMISSIONS); ensure all
examples and enum mentions use the chosen token consistently.
| ```python | ||
| class APIClient: | ||
| def __init__(self, base_url, min_version="2.0.0"): | ||
| self.version_info = requests.get(f"{base_url}/version").json() | ||
|
|
||
| if not self._version_compatible(min_version): | ||
| raise IncompatibleVersionError(...) | ||
|
|
||
| if self.version_info.get("deprecations"): | ||
| self._alert_operator() | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Pattern 3: Machine-Readable Quick Reference | ||
|
|
||
| ### YAML Format | ||
|
|
||
| ```yaml | ||
| # agent-quickstart.yaml | ||
| api: | ||
| base_url: https://api.example.com/v1 | ||
| auth: Bearer token in Authorization header | ||
| rate_limit: 100 requests/minute | ||
|
|
||
| endpoints: | ||
| - name: create_resource | ||
| method: POST | ||
| path: /resources | ||
| requires_auth: true | ||
| request_schema: ./schemas/create_resource.json | ||
| response_schema: ./schemas/resource.json | ||
| errors: | ||
| - VALIDATION_FAILED | ||
| - AUTH_TOKEN_EXPIRED | ||
| - QUOTA_EXCEEDED | ||
| ``` | ||
|
|
||
| ### JSON Schema for Requests | ||
|
|
||
| ```json | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "type": "object", | ||
| "required": ["name", "type"], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "minLength": 1, | ||
| "maxLength": 100, | ||
| "description": "Resource name" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["standard", "premium", "enterprise"], | ||
| "description": "Resource tier" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Pattern 4: Headless API Design | ||
|
|
||
| ### Status Endpoint | ||
|
|
||
| ```json | ||
| GET /status | ||
|
|
||
| { | ||
| "status": "running", | ||
| "version": "1.2.3", | ||
| "uptime_seconds": 86400, | ||
| "last_action": "process_item", | ||
| "pending_actions": 3, | ||
| "metrics": { | ||
| "items_processed": 1523, | ||
| "errors": 2 | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Command Endpoint | ||
|
|
||
| ```json | ||
| POST /command | ||
| { | ||
| "command": "execute", | ||
| "params": { | ||
| "action": "process_item", | ||
| "item_id": "abc123" | ||
| } | ||
| } | ||
|
|
||
| Response: | ||
| { | ||
| "status": "queued", | ||
| "command_id": "cmd_xyz789", | ||
| "estimated_execution": "2026-03-05T14:30:05Z" | ||
| } | ||
| ``` | ||
|
|
||
| ### Events (SSE) | ||
|
|
||
| ```javascript | ||
| const events = new EventSource('/events'); | ||
| events.onmessage = (e) => { | ||
| const data = JSON.parse(e.data); | ||
| // Handle: tick, action, error, state_change | ||
| }; | ||
| ``` |
There was a problem hiding this comment.
Add at least one starknet.js-based example.
The examples are currently generic; this skill is missing a concrete starknet.js pattern example, which is required by the skill documentation convention.
As per coding guidelines: "Skills must include code examples with starknet.js patterns".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/agentic-documentation/SKILL.md` around lines 135 - 246, Add a concrete
starknet.js example to SKILL.md (e.g., under Pattern 3 or Pattern 4) that
demonstrates using starknet.js primitives: instantiate a Provider/Account, build
and sign an invokeTransaction, send it (account.execute or
provider.sendTransaction), and poll for receipt
(provider.getTransactionReceipt), plus show expected request/response shapes;
ensure the snippet is labeled "starknet.js Example" and references the library
names (Provider, Account, invokeFunction/getTransactionReceipt) so readers can
find it quickly.
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "build": "tsc -p tsconfig.json", | ||
| "test": "bun test ./src/strategy-marketplace.test.ts" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Verify whether Bun is an established repo toolchain requirement.
echo "== package manager / engine hints =="
rg -n --glob '**/package.json' '"packageManager"|"engines"|"bun test"|"\bbun\b' | head -20
echo "== CI workflow references to bun =="
rg -n --glob '.github/workflows/**/*.yml' --glob '.github/workflows/**/*.yaml' '\bbun\b' | head -20
echo "== docs/setup references to bun =="
rg -n --glob 'README.md' --glob '**/README.md' --glob 'AGENT.md' --glob 'CLAUDE.md' '\bbun\b' | head -20
echo "== root package.json check =="
head -30 package.json 2>/dev/null || echo "No root package.json found"Repository: keep-starknet-strange/starknet-agentic
Length of output: 664
🏁 Script executed:
cat -n package.json | head -40Repository: keep-starknet-strange/starknet-agentic
Length of output: 1244
Test script uses Bun without declaring it as a repo-level requirement.
The root package.json explicitly establishes pnpm@10.28.2 as the package manager and Node.js >=20.9.0 as the runtime. This test script breaks the toolchain contract: when contributors run pnpm -r test or install dependencies as documented, the Bun CLI will not be available, causing the test to fail. Either declare Bun in the engines field and update repo setup docs/CI, or migrate the test script to use a supported test runner (vitest is already in devDependencies).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/package.json` at line 10, The package.json test
script currently calls Bun ("test": "bun test
./src/strategy-marketplace.test.ts") but Bun is not declared as a repo-level
requirement; update package.json to replace the Bun invocation by the
repo-supported test runner already in devDependencies (vitest) by changing the
"test" script to run vitest (e.g., "test": "vitest
./src/strategy-marketplace.test.ts" or equivalent CLI flags used across the
repo), ensuring the test runs under the declared Node/pnpm toolchain;
alternatively, if you intend to require Bun, add Bun to the repo-level
requirements (engines/CI/docs) and declare it accordingly—but prefer migrating
the "test" script to use the existing "vitest" devDependency.
| async function verifyPaymentStub( | ||
| buyerAgentId: string, | ||
| strategyId: string, | ||
| expectedPrice: number | ||
| ): Promise<boolean> { | ||
| void buyerAgentId; | ||
| void strategyId; | ||
| void expectedPrice; | ||
| // Placeholder for x402 settlement hook. | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Fail-open payment verifier allows zero-cost purchases
Line 407 returns true unconditionally, so purchaseStrategy accepts every purchase without proof of payment. This is a critical authorization/billing bypass.
🔒 Proposed fix (fail closed until a real verifier is wired)
async function verifyPaymentStub(
buyerAgentId: string,
strategyId: string,
expectedPrice: number
): Promise<boolean> {
void buyerAgentId;
void strategyId;
void expectedPrice;
- // Placeholder for x402 settlement hook.
- return true;
+ // Fail closed until a real settlement verifier is implemented.
+ throw new Error('PAYMENT_VERIFICATION_NOT_IMPLEMENTED');
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async function verifyPaymentStub( | |
| buyerAgentId: string, | |
| strategyId: string, | |
| expectedPrice: number | |
| ): Promise<boolean> { | |
| void buyerAgentId; | |
| void strategyId; | |
| void expectedPrice; | |
| // Placeholder for x402 settlement hook. | |
| return true; | |
| } | |
| async function verifyPaymentStub( | |
| buyerAgentId: string, | |
| strategyId: string, | |
| expectedPrice: number | |
| ): Promise<boolean> { | |
| void buyerAgentId; | |
| void strategyId; | |
| void expectedPrice; | |
| // Fail closed until a real settlement verifier is implemented. | |
| throw new Error('PAYMENT_VERIFICATION_NOT_IMPLEMENTED'); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/marketplace.ts` around lines 398 - 408, The
verifyPaymentStub function currently always returns true which allows free
purchases; change it to fail-closed by returning false (or throwing a clear
error) until a real payment verifier is implemented, update the function
verifyPaymentStub signature usage so purchase logic (e.g., purchaseStrategy)
treats a false result as a failed payment and aborts the purchase flow, and add
a TODO comment referencing the real x402 settlement hook to remind future wiring
of the real verifier.
| type RegistryState = { agents: Map<string, RegisteredAgent> }; | ||
|
|
||
| function getRegistryState(): RegistryState { | ||
| const globalState = globalThis as typeof globalThis & { | ||
| __strategyMarketplaceRegistryState?: RegistryState; | ||
| }; | ||
| if (!globalState.__strategyMarketplaceRegistryState) { | ||
| globalState.__strategyMarketplaceRegistryState = { | ||
| agents: new Map<string, RegisteredAgent>() | ||
| }; | ||
| } | ||
| return globalState.__strategyMarketplaceRegistryState; |
There was a problem hiding this comment.
generateAgentId() breaks ERC-8004 parity by using random IDs.
The fallback should emulate contract behavior (monotonic u256 token IDs) rather than random bytes; otherwise local IDs won’t map predictably to on-chain identity registries.
Suggested parity-safe fallback
-type RegistryState = { agents: Map<string, RegisteredAgent> };
+type RegistryState = {
+ agents: Map<string, RegisteredAgent>;
+ nextTokenId: bigint;
+};
if (!globalState.__strategyMarketplaceRegistryState) {
globalState.__strategyMarketplaceRegistryState = {
- agents: new Map<string, RegisteredAgent>()
+ agents: new Map<string, RegisteredAgent>(),
+ nextTokenId: 1n
};
}
function generateAgentId(): string {
- // In production, use token_id emitted from ERC-8004 mint transfer event.
+ // In production, use token_id emitted from ERC-8004 mint transfer event.
const mintedTokenId = process.env.ERC8004_TOKEN_ID;
if (mintedTokenId) {
+ if (!/^(0x[0-9a-fA-F]+|[0-9]+)$/.test(mintedTokenId)) {
+ throw new Error('Invalid ERC8004_TOKEN_ID: expected u256 (decimal or hex)');
+ }
return mintedTokenId;
}
- return `0x${randomBytes(32).toString('hex')}`;
+ const state = getRegistryState();
+ const id = state.nextTokenId;
+ state.nextTokenId += 1n;
+ return id.toString();
}Also applies to: 103-110
| it('publishes, discovers, and purchases strategies', async () => { | ||
| const agent = await registerAgent({ | ||
| name: 'market-maker', | ||
| description: 'Makes calibrated decisions', | ||
| capabilities: ['strategy'], | ||
| games: ['loot-survivor'], | ||
| network: 'SN_MAIN' | ||
| }); | ||
|
|
||
| const listing = await publishStrategy({ | ||
| agentId: agent.id, | ||
| name: 'Low Risk Survival', | ||
| description: 'Defensive playbook', | ||
| price: '0.01', | ||
| game: 'loot-survivor', | ||
| parameters: { riskLevel: 'low', playStyle: 'defensive', minCapital: '10' }, | ||
| trackRecord: { wins: 6, losses: 4, avgRoi: 1.4, totalGames: 10 } | ||
| }); | ||
|
|
||
| expect(listing.certified).toBeTrue(); | ||
|
|
||
| const discovered = await discoverStrategies({ game: 'loot-survivor', minRoi: 1.0, sortBy: 'roi', limit: 5 }); | ||
| expect(discovered.length).toBe(1); | ||
| expect(discovered[0].id).toBe(listing.id); | ||
|
|
||
| const purchase = await purchaseStrategy({ strategyId: listing.id, buyerAgentId: agent.id }); | ||
| expect(purchase.success).toBeTrue(); | ||
| expect(purchase.accessId.startsWith('acc_')).toBeTrue(); | ||
| }); | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Use a distinct buyer agent in purchase-flow test.
Line 109 currently purchases with the same agent that published the strategy. This misses cross-agent marketplace behavior and can mask self-purchase rule bugs.
Proposed test adjustment
const listing = await publishStrategy({
agentId: agent.id,
name: 'Low Risk Survival',
description: 'Defensive playbook',
price: '0.01',
game: 'loot-survivor',
parameters: { riskLevel: 'low', playStyle: 'defensive', minCapital: '10' },
trackRecord: { wins: 6, losses: 4, avgRoi: 1.4, totalGames: 10 }
});
+ const buyer = await registerAgent({
+ name: 'strategy-buyer',
+ description: 'Buys strategies',
+ capabilities: ['strategy'],
+ games: ['loot-survivor'],
+ network: 'SN_MAIN'
+ });
+
expect(listing.certified).toBeTrue();
const discovered = await discoverStrategies({ game: 'loot-survivor', minRoi: 1.0, sortBy: 'roi', limit: 5 });
expect(discovered.length).toBe(1);
expect(discovered[0].id).toBe(listing.id);
- const purchase = await purchaseStrategy({ strategyId: listing.id, buyerAgentId: agent.id });
+ const purchase = await purchaseStrategy({ strategyId: listing.id, buyerAgentId: buyer.id });
expect(purchase.success).toBeTrue();
expect(purchase.accessId.startsWith('acc_')).toBeTrue();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('publishes, discovers, and purchases strategies', async () => { | |
| const agent = await registerAgent({ | |
| name: 'market-maker', | |
| description: 'Makes calibrated decisions', | |
| capabilities: ['strategy'], | |
| games: ['loot-survivor'], | |
| network: 'SN_MAIN' | |
| }); | |
| const listing = await publishStrategy({ | |
| agentId: agent.id, | |
| name: 'Low Risk Survival', | |
| description: 'Defensive playbook', | |
| price: '0.01', | |
| game: 'loot-survivor', | |
| parameters: { riskLevel: 'low', playStyle: 'defensive', minCapital: '10' }, | |
| trackRecord: { wins: 6, losses: 4, avgRoi: 1.4, totalGames: 10 } | |
| }); | |
| expect(listing.certified).toBeTrue(); | |
| const discovered = await discoverStrategies({ game: 'loot-survivor', minRoi: 1.0, sortBy: 'roi', limit: 5 }); | |
| expect(discovered.length).toBe(1); | |
| expect(discovered[0].id).toBe(listing.id); | |
| const purchase = await purchaseStrategy({ strategyId: listing.id, buyerAgentId: agent.id }); | |
| expect(purchase.success).toBeTrue(); | |
| expect(purchase.accessId.startsWith('acc_')).toBeTrue(); | |
| }); | |
| it('publishes, discovers, and purchases strategies', async () => { | |
| const agent = await registerAgent({ | |
| name: 'market-maker', | |
| description: 'Makes calibrated decisions', | |
| capabilities: ['strategy'], | |
| games: ['loot-survivor'], | |
| network: 'SN_MAIN' | |
| }); | |
| const listing = await publishStrategy({ | |
| agentId: agent.id, | |
| name: 'Low Risk Survival', | |
| description: 'Defensive playbook', | |
| price: '0.01', | |
| game: 'loot-survivor', | |
| parameters: { riskLevel: 'low', playStyle: 'defensive', minCapital: '10' }, | |
| trackRecord: { wins: 6, losses: 4, avgRoi: 1.4, totalGames: 10 } | |
| }); | |
| const buyer = await registerAgent({ | |
| name: 'strategy-buyer', | |
| description: 'Buys strategies', | |
| capabilities: ['strategy'], | |
| games: ['loot-survivor'], | |
| network: 'SN_MAIN' | |
| }); | |
| expect(listing.certified).toBeTrue(); | |
| const discovered = await discoverStrategies({ game: 'loot-survivor', minRoi: 1.0, sortBy: 'roi', limit: 5 }); | |
| expect(discovered.length).toBe(1); | |
| expect(discovered[0].id).toBe(listing.id); | |
| const purchase = await purchaseStrategy({ strategyId: listing.id, buyerAgentId: buyer.id }); | |
| expect(purchase.success).toBeTrue(); | |
| expect(purchase.accessId.startsWith('acc_')).toBeTrue(); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/strategy-marketplace.test.ts` around lines 84
- 113, The test uses the same agent for publishing and buying which hides
cross-agent behavior; update the test around
registerAgent/publishStrategy/purchaseStrategy so you create a second agent
(e.g., buyerAgent via registerAgent) and call purchaseStrategy with
buyerAgent.id instead of agent.id; change assertions if needed to reference
buyerAgent where purchase ownership or access is validated and ensure
discover/publish still use the original agent variable and
publishStrategy/listing remain unchanged.
| it('rejects invalid registration and performance payloads', async () => { | ||
| await expect(registerAgent({ | ||
| name: 'Invalid Name', | ||
| description: 'bad', | ||
| capabilities: ['gaming'], | ||
| games: ['loot-survivor'], | ||
| network: 'SN_MAIN' | ||
| })).rejects.toThrow(); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Negative-path assertions are too broad with bare toThrow().
Using only rejects.toThrow() can pass on unrelated exceptions. Prefer asserting a stable error contract (at least code/category/retryable or specific message) per failure case.
Example tightening for one validation case
await expect(trackPerformance({
agentId: agent.id,
game: 'loot-survivor',
result: 'win',
roi: 1.2,
strategy: 'alpha',
duration: -1
- })).rejects.toThrow();
+ })).rejects.toMatchObject({
+ code: expect.any(String),
+ category: 'validation',
+ retryable: false
+ });Also applies to: 153-160, 172-180, 182-185, 187-187
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/strategy-marketplace.test.ts` around lines
136 - 143, The test uses a bare rejects.toThrow() which is too broad; update the
assertions in the failing test cases (the test calling registerAgent(...) and
the other similar tests) to assert a specific, stable error contract from the
validation layer—e.g., expect(registerAgent(...)).rejects.toThrowError(/specific
validation message/) or expect(...).rejects.toMatchObject({ code:
'INVALID_PAYLOAD' }) or check a boolean property like error.retryable === false;
locate the calls to registerAgent and other tested functions in this file (the
it('rejects invalid registration and performance payloads') block and the other
blocks at the referenced ranges) and replace bare toThrow() with explicit
message or object-matching assertions that reflect the validator's error shape.
| export async function getAgentStats(agentId: string): Promise<AgentStats> { | ||
| const normalizedAgentId = requireNonEmptyString(agentId, 'agentId'); | ||
| const performances = await getPerformanceHistory(normalizedAgentId); | ||
|
|
||
| if (performances.length === 0) { | ||
| return { | ||
| agentId: normalizedAgentId, | ||
| totalGames: 0, | ||
| wins: 0, | ||
| losses: 0, | ||
| draws: 0, | ||
| totalRoi: 0, | ||
| avgRoi: 0, | ||
| gamesByType: {}, | ||
| strategies: {} | ||
| }; | ||
| } |
There was a problem hiding this comment.
getAgentStats silently accepts unknown agent IDs.
Returning zeroed stats for non-existent agents hides caller mistakes and propagates misleading values through getWinRate. Validate agent existence first, then return empty stats only for existing agents with no history.
Targeted fix
export async function getAgentStats(agentId: string): Promise<AgentStats> {
const normalizedAgentId = requireNonEmptyString(agentId, 'agentId');
+ const agent = await getAgent(normalizedAgentId);
+ if (!agent) {
+ throw new Error(`Agent not found: ${normalizedAgentId}`);
+ }
const performances = await getPerformanceHistory(normalizedAgentId);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/tracking.ts` around lines 51 - 67,
getAgentStats currently treats any unknown agentId as an existing agent by
returning zeroed stats after calling getPerformanceHistory; instead, first
validate the agent exists (e.g., call your project’s agent lookup such as
getAgentById or fetchAgent) inside getAgentStats before returning empty stats,
and only return zeroed stats when the agent is confirmed to exist but has no
performance history; update callers like getWinRate will then correctly surface
errors for nonexistent agents rather than misleading zeros.
…rage - Add JSDoc comments to all exported and internal functions - Document all TypeScript interfaces with property descriptions - Fixes docstring coverage from 32.69% to 80%+ - Addresses CodeRabbit pre-merge check failure
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/strategy-marketplace/src/marketplace.ts`:
- Around line 152-161: The expiresAt timestamp in the PurchaseResult object
(constructed as const access) is using Date.now() milliseconds which will
mismatch on-chain seconds; change the computation for expiresAt to use seconds
(e.g. Math.floor(Date.now()/1000) + 3600) so it aligns with blockchain
timestamps—update where access is created (expiresAt) and any related
comparisons that expect seconds.
- Around line 367-384: The validateTrackRecord function currently allows wins +
losses < totalGames without accounting for draws; update validateTrackRecord to
compute implicit draws = totalGames - wins - losses and either (A) add an
explicit draws field to StrategyListing['trackRecord'] and validate/return it,
or (B) validate that draws >= 0 and document that totalGames - wins - losses
represents draws and return the computed draws alongside wins, losses,
totalGames, avgRoi; ensure you update the function signature/return shape and
any callers that consume validateTrackRecord so they handle the new draws
property or the clarified invariant.
In `@skills/strategy-marketplace/src/registry.ts`:
- Around line 51-60: registeredAt is using Date.now() (milliseconds) which
mismatches on-chain seconds; update the code that builds the RegisteredAgent
object (the registeredAt field in the agent created alongside generateAgentId(),
getCurrentAgentAddress(), network, name, etc.) to set a seconds-based timestamp
(e.g. Math.floor(Date.now() / 1000) or equivalent) so local agent timestamps
align with Starknet/blockchain seconds-based timestamps.
- Around line 9-19: MARKETPLACE_CONTRACTS currently uses ambiguous placeholders
('0x...') for SN_MAIN and SN_SEPOLIA registry/marketplace addresses which can be
mistaken for real addresses; update the constants to use clearly invalid
addresses (e.g., '0x0000000000000000000000000000000000000000' or
'INVALID_ADDRESS') and add a runtime validation function (used at module init or
in functions that read MARKETPLACE_CONTRACTS) that checks
MARKETPLACE_CONTRACTS.SN_MAIN.registry,
MARKETPLACE_CONTRACTS.SN_MAIN.marketplace,
MARKETPLACE_CONTRACTS.SN_SEPOLIA.registry and
MARKETPLACE_CONTRACTS.SN_SEPOLIA.marketplace and throws or logs a clear error if
any value matches the placeholder pattern so callers cannot proceed with
non-functional addresses.
In `@skills/strategy-marketplace/src/tracking.ts`:
- Around line 194-200: Extract the duplicated requireNonEmptyString helper into
a shared module (e.g., create skills/strategy-marketplace/src/validation.ts),
export requireNonEmptyString (and also add requireFiniteNumber per the
suggestion), then replace the local definitions in tracking.ts, registry.ts, and
marketplace.ts to import { requireNonEmptyString, requireFiniteNumber } from
that new module; ensure all call sites still pass the same parameters and that
TypeScript imports/exports are updated accordingly.
- Around line 42-45: The timestamp default currently uses Date.now()
(milliseconds) when building the PerformanceRecord in the performance constant;
change the fallback to seconds by using Math.floor(Date.now() / 1000) so the
PerformanceRecord.timestamp (and the PerformanceRecord type usage) is consistent
with blockchain seconds-based timestamps and with validatedRecord.timestamp when
present.
- Around line 223-249: validatePerformanceInput is missing runtime validation
for the result field; add a check that record.result is one of the allowed
values ('win', 'loss', 'draw') by reading record.result, ensuring it's a
non-empty string (use requireNonEmptyString or equivalent) and then verifying it
against a small allowed set, throwing a clear Error on mismatch, and include the
validated result value in the returned object so callers get the
normalized/validated result.
In `@skills/strategy-marketplace/src/types.ts`:
- Around line 113-120: parameters.minCapital is typed as string while other
monetary fields like price use number, causing inconsistency; make the types
consistent by updating the type of parameters.minCapital to match price (or
change price to string if you prefer string precision) across the types
module—update the parameters definition (parameters.minCapital) and any related
interfaces/usages that read or write minCapital to use the chosen numeric/string
type and add a brief comment about units/precision; ensure compile-time type
changes cascade to functions that consume minCapital so no type errors remain.
- Around line 108-109: Change the price fields from number to a non-floating
type to avoid precision loss: update StrategyListing.price and
ServiceOffering.price to either bigint (recommended: store STRK in smallest
unit/wei as BigInt) or string (decimal-library-compatible) throughout the
codebase, and adjust all places that construct, serialize/deserialize, or
perform arithmetic on these prices to convert to/from the chosen representation
(including API payloads, DB reads/writes, and any math operations) and add a
comment mentioning STRK has 18 decimals so callers know to use smallest-unit
values or a decimal library.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4b2f73b0-1904-49f9-8364-fc70bc696e25
📒 Files selected for processing (4)
skills/strategy-marketplace/src/marketplace.tsskills/strategy-marketplace/src/registry.tsskills/strategy-marketplace/src/tracking.tsskills/strategy-marketplace/src/types.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: Consult the `references/agentskills/` directory for AgentSkills specifications covering integration patterns, skill format, and skill definitions
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to **/skills/*/SKILL.md : Skills must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable metadata in a SKILL.md file
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to skills/**/SKILL.md : Skill definitions must follow the AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/*/SKILL.md : Skill files must follow AgentSkills convention with YAML frontmatter including name, description, keywords, allowed-tools, and user-invocable flag
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:53:48.727Z
Learning: Applies to skills/**/SKILL.md : Include code examples with starknet.js patterns in skill documentation
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Applies to skills/**/{SKILL.md,references/**/*,scripts/**/*.{ts,py}} : Skills must include SKILL.md documentation, reference documentation in references/ subdirectory, and runnable TypeScript/Python examples in scripts/ subdirectory
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to skills/**/{SKILL.md,references/**,scripts/**} : Documentation for skills must include quick reference in SKILL.md, deep-dive topics in `references/` subdirectory, and runnable examples in `scripts/` subdirectory
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Consult the `references/` directory (especially `references/starknet-docs/` and `references/agentskills/`) as the authoritative knowledge base before writing skills, contracts, or integrations
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Agent-safe operations include reading/analyzing files, writing TypeScript/Cairo source, tests, skills and docs, running builds/tests, and creating new skills following established patterns
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Always consult the `references/` directory (Starknet documentation and AgentSkills specs) before writing skills, contracts, or integrations
📚 Learning: 2026-02-21T11:12:59.733Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-21T11:12:59.733Z
Learning: Applies to packages/**/*.ts : Lucid Agents integration must implement the Extension interface with WalletConnector using lucid-agents/types
Applied to files:
skills/strategy-marketplace/src/types.tsskills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/starknet-a2a/**/*.{ts,tsx,js} : Agent-to-Agent communication must implement the A2A protocol for agent discovery and interoperability
Applied to files:
skills/strategy-marketplace/src/types.tsskills/strategy-marketplace/src/marketplace.tsskills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/**/*.{ts,tsx} : TypeScript/JavaScript packages must use proper type definitions and follow the extension patterns for Daydreams and Lucid Agents integrations
Applied to files:
skills/strategy-marketplace/src/types.ts
📚 Learning: 2026-02-16T23:56:29.389Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T23:56:29.389Z
Learning: Applies to **/packages/starknet-mcp-server/tools/**/*.{ts,tsx,js} : DeFi integrations should use the avnu aggregator SDK and follow the avnu Skill patterns for swaps, DCA, staking, gasless, and gasfree implementations
Applied to files:
skills/strategy-marketplace/src/types.ts
📚 Learning: 2026-02-16T05:58:24.900Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-16T05:58:24.900Z
Learning: Applies to +(contracts,packages)/**/{**/*account*,**/*session*,**/*signature*,**/*key*}.{cairo,ts,tsx} : Require human review for security-sensitive code (key handling, signature verification, spending limits)
Applied to files:
skills/strategy-marketplace/src/marketplace.ts
📚 Learning: 2026-02-16T20:43:37.314Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:43:37.314Z
Learning: Use ERC-8004 (Cairo implementation) for on-chain agent identity, reputation, and validation registry functionality
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to contracts/**/*{identity,reputation,validation}*.{cairo,test.*} : Implement ERC-8004 identity, reputation, and validation registries with production-ready unit and E2E testing coverage
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to packages/create-starknet-agent/**/*.{ts,tsx,js} : CLI scaffolding tool (`create-starknet-agent`) must provide E2E onboarding examples for agent setup on Starknet
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Applies to contracts/**/*{identity,reputation,validation}*.cairo : Agent identity and reputation must use the ERC-8004 standard with Cairo contract implementations
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T05:58:24.900Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T05:58:24.900Z
Learning: Applies to contracts/agent-account/**/*.cairo : Agent Account contract must implement extended Starknet native account abstraction with session keys, spending policies, time bounds, paymaster support, and event logging
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T20:44:56.184Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T20:44:56.184Z
Learning: Applies to **/contracts/agent-account/**/*.{test,spec}.{ts,tsx,cairo} : Agent Account contract must be tested with at least 110 unit tests and E2E tests before production deployment
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T05:58:24.900Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T05:58:24.900Z
Learning: Applies to **/contracts/agent-account/**/*.cairo : Agent Account contracts must support session keys, spending limits, time bounds, kill switches, multi-call batching, and nonce abstraction according to the Agent Wallet Architecture specification
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-15T17:03:57.943Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-15T17:03:57.943Z
Learning: Always consult the `references/` directory (Starknet documentation and AgentSkills specs) before writing skills, contracts, or integrations
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-17T00:51:57.102Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-17T00:51:57.102Z
Learning: Consult the `references/` directory (especially `references/starknet-docs/` and `references/agentskills/`) as the authoritative knowledge base before writing skills, contracts, or integrations
Applied to files:
skills/strategy-marketplace/src/registry.ts
📚 Learning: 2026-02-16T05:58:24.900Z
Learnt from: CR
Repo: keep-starknet-strange/starknet-agentic PR: 0
File: AGENT.md:0-0
Timestamp: 2026-02-16T05:58:24.900Z
Learning: CLI scaffolding tool (`create-starknet-agent`) should provide E2E onboarding examples and cross-chain agent registration capabilities
Applied to files:
skills/strategy-marketplace/src/registry.ts
🔇 Additional comments (10)
skills/strategy-marketplace/src/types.ts (1)
1-202: LGTM!The type definitions are well-structured with comprehensive JSDoc documentation, appropriate use of string literal unions for constrained values, and generic types for flexible purchase request/result handling. The interfaces provide a clear contract for the marketplace domain model.
skills/strategy-marketplace/src/registry.ts (2)
114-121:generateAgentId()uses random IDs incompatible with ERC-8004 token IDs.This concern was previously raised. The ERC-8004 Cairo contract uses a monotonic counter starting at 1 (see
contracts/erc8004-cairo/src/identity_registry.cairo), while this function generates random 32-byte hex strings. These will never match real on-chain token IDs and could collide.
169-230: LGTM on validation helpers.The validation functions (
requireNonEmptyString,requireStringArray,validateRegistrationInput,validateUpdateInput) are well-implemented with:
- Proper trimming and normalization
- Clear error messages with field names
- Deduplication in
requireStringArray- Regex validation for agent names via
SKILL_NAME_PATTERNskills/strategy-marketplace/src/tracking.ts (2)
56-72:getAgentStatsstill silently accepts unknown agent IDs.This issue was previously raised. The function returns zeroed stats for any
agentIdwithout verifying the agent exists in the registry, which can mask caller errors and propagate misleading data throughgetWinRateandgetTopStrategies.
74-112: LGTM on stats aggregation logic.The
getAgentStatscomputation correctly:
- Filters by result type for wins/losses/draws
- Accumulates ROI totals
- Groups games by type and tracks per-strategy metrics
- Computes averages safely (after checking
performances.length > 0)skills/strategy-marketplace/src/marketplace.ts (5)
54-56: Public errors still use free-form messages, blocking machine-readable agent branching.This issue was previously raised. The marketplace throws generic
Errorinstances with free-form messages, making it difficult for agents to programmatically categorize errors, determine retryability, or implement automated retry logic.Also applies to: 138-140, 143-145, 149-150, 180-182
277-294: Internal marketplace state remains externally mutable via returned object references.This issue was previously raised.
getAllListings()andgetAllOfferings()return shallow copies of arrays containing the original object references. Callers can mutate these objects and corrupt internal state.Also applies to: 301-318
505-515: Fail-open payment verifier still allows zero-cost purchases.This critical issue was previously raised.
verifyPaymentStubreturnstrueunconditionally, allowing any purchase without payment verification.
87-120: LGTM on discovery filtering and sorting logic.The
discoverStrategiesfunction correctly:
- Validates the query parameters
- Applies optional filters for game, minRoi, and maxPrice
- Supports multiple sort options (roi, wins, price, recent)
- Applies limit with sensible default (20)
393-432: LGTM on publish validation.
validatePublishStrategyInputprovides thorough validation including nestedparametersfields and delegates tovalidateTrackRecordfor consistency checks.
| const access: PurchaseResult = { | ||
| success: true, | ||
| accessId: generateAccessId(), | ||
| strategyData: { | ||
| name: strategy.name, | ||
| parameters: strategy.parameters, | ||
| trackRecord: strategy.trackRecord | ||
| }, | ||
| expiresAt: Date.now() + 3600000 // 1 hour | ||
| }; |
There was a problem hiding this comment.
Timestamp uses milliseconds; should use seconds for consistency.
expiresAt is computed using Date.now() (milliseconds) plus an offset, but blockchain timestamps use seconds. If this value is later compared with on-chain data, it will be off by a factor of 1000.
🔧 Proposed fix
const access: PurchaseResult = {
success: true,
accessId: generateAccessId(),
strategyData: {
name: strategy.name,
parameters: strategy.parameters,
trackRecord: strategy.trackRecord
},
- expiresAt: Date.now() + 3600000 // 1 hour
+ expiresAt: Math.floor(Date.now() / 1000) + 3600 // 1 hour (in seconds)
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const access: PurchaseResult = { | |
| success: true, | |
| accessId: generateAccessId(), | |
| strategyData: { | |
| name: strategy.name, | |
| parameters: strategy.parameters, | |
| trackRecord: strategy.trackRecord | |
| }, | |
| expiresAt: Date.now() + 3600000 // 1 hour | |
| }; | |
| const access: PurchaseResult = { | |
| success: true, | |
| accessId: generateAccessId(), | |
| strategyData: { | |
| name: strategy.name, | |
| parameters: strategy.parameters, | |
| trackRecord: strategy.trackRecord | |
| }, | |
| expiresAt: Math.floor(Date.now() / 1000) + 3600 // 1 hour (in seconds) | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/marketplace.ts` around lines 152 - 161, The
expiresAt timestamp in the PurchaseResult object (constructed as const access)
is using Date.now() milliseconds which will mismatch on-chain seconds; change
the computation for expiresAt to use seconds (e.g. Math.floor(Date.now()/1000) +
3600) so it aligns with blockchain timestamps—update where access is created
(expiresAt) and any related comparisons that expect seconds.
| function validateTrackRecord(trackRecord: StrategyListing['trackRecord']): StrategyListing['trackRecord'] { | ||
| const wins = Math.trunc(requireFiniteNumber(trackRecord.wins, 'trackRecord.wins')); | ||
| const losses = Math.trunc(requireFiniteNumber(trackRecord.losses, 'trackRecord.losses')); | ||
| const totalGames = Math.trunc(requireFiniteNumber(trackRecord.totalGames, 'trackRecord.totalGames')); | ||
| const avgRoi = requireFiniteNumber(trackRecord.avgRoi, 'trackRecord.avgRoi'); | ||
|
|
||
| if (wins < 0 || losses < 0 || totalGames < 0) { | ||
| throw new Error('Invalid trackRecord: wins, losses, and totalGames must be non-negative'); | ||
| } | ||
| if (totalGames === 0) { | ||
| throw new Error('Invalid trackRecord: totalGames must be greater than 0'); | ||
| } | ||
| if (wins + losses > totalGames) { | ||
| throw new Error('Invalid trackRecord: wins + losses cannot exceed totalGames'); | ||
| } | ||
|
|
||
| return { wins, losses, totalGames, avgRoi }; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
validateTrackRecord allows wins + losses < totalGames without accounting for draws.
The validation checks that wins + losses <= totalGames but doesn't validate the relationship with draws. If totalGames = wins + losses + draws, then totalGames - wins - losses should represent implicit draws. Consider either:
- Adding an explicit
drawsfield totrackRecord - Documenting that
totalGames - wins - lossesrepresents draws
This could lead to inconsistent data if callers don't understand the implicit relationship.
💡 Suggested documentation
function validateTrackRecord(trackRecord: StrategyListing['trackRecord']): StrategyListing['trackRecord'] {
const wins = Math.trunc(requireFiniteNumber(trackRecord.wins, 'trackRecord.wins'));
const losses = Math.trunc(requireFiniteNumber(trackRecord.losses, 'trackRecord.losses'));
const totalGames = Math.trunc(requireFiniteNumber(trackRecord.totalGames, 'trackRecord.totalGames'));
const avgRoi = requireFiniteNumber(trackRecord.avgRoi, 'trackRecord.avgRoi');
if (wins < 0 || losses < 0 || totalGames < 0) {
throw new Error('Invalid trackRecord: wins, losses, and totalGames must be non-negative');
}
if (totalGames === 0) {
throw new Error('Invalid trackRecord: totalGames must be greater than 0');
}
if (wins + losses > totalGames) {
- throw new Error('Invalid trackRecord: wins + losses cannot exceed totalGames');
+ throw new Error('Invalid trackRecord: wins + losses cannot exceed totalGames (difference represents draws)');
}
return { wins, losses, totalGames, avgRoi };
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/marketplace.ts` around lines 367 - 384, The
validateTrackRecord function currently allows wins + losses < totalGames without
accounting for draws; update validateTrackRecord to compute implicit draws =
totalGames - wins - losses and either (A) add an explicit draws field to
StrategyListing['trackRecord'] and validate/return it, or (B) validate that
draws >= 0 and document that totalGames - wins - losses represents draws and
return the computed draws alongside wins, losses, totalGames, avgRoi; ensure you
update the function signature/return shape and any callers that consume
validateTrackRecord so they handle the new draws property or the clarified
invariant.
| // Marketplace contract addresses (placeholder - deploy later) | ||
| const MARKETPLACE_CONTRACTS = { | ||
| SN_MAIN: { | ||
| registry: '0x...', // ERC-8004 registry | ||
| marketplace: '0x...' | ||
| }, | ||
| SN_SEPOLIA: { | ||
| registry: '0x...', | ||
| marketplace: '0x...' | ||
| } | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Placeholder contract addresses need clearer indication they're non-functional.
The '0x...' placeholder values could be mistaken for truncated real addresses in logs or debugging. Consider using explicitly invalid addresses or adding runtime checks.
💡 Suggested improvement
const MARKETPLACE_CONTRACTS = {
SN_MAIN: {
- registry: '0x...', // ERC-8004 registry
- marketplace: '0x...'
+ registry: '0x0000000000000000000000000000000000000000000000000000000000000000', // TODO: Deploy ERC-8004 registry
+ marketplace: '0x0000000000000000000000000000000000000000000000000000000000000000' // TODO: Deploy marketplace
},
SN_SEPOLIA: {
- registry: '0x...',
- marketplace: '0x...'
+ registry: '0x0000000000000000000000000000000000000000000000000000000000000000', // TODO: Deploy to Sepolia
+ marketplace: '0x0000000000000000000000000000000000000000000000000000000000000000'
}
-};
+} as const;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/registry.ts` around lines 9 - 19,
MARKETPLACE_CONTRACTS currently uses ambiguous placeholders ('0x...') for
SN_MAIN and SN_SEPOLIA registry/marketplace addresses which can be mistaken for
real addresses; update the constants to use clearly invalid addresses (e.g.,
'0x0000000000000000000000000000000000000000' or 'INVALID_ADDRESS') and add a
runtime validation function (used at module init or in functions that read
MARKETPLACE_CONTRACTS) that checks MARKETPLACE_CONTRACTS.SN_MAIN.registry,
MARKETPLACE_CONTRACTS.SN_MAIN.marketplace,
MARKETPLACE_CONTRACTS.SN_SEPOLIA.registry and
MARKETPLACE_CONTRACTS.SN_SEPOLIA.marketplace and throws or logs a clear error if
any value matches the placeholder pattern so callers cannot proceed with
non-functional addresses.
| const agent: RegisteredAgent = { | ||
| id: generateAgentId(), | ||
| address: getCurrentAgentAddress(), | ||
| network, | ||
| name, | ||
| description, | ||
| capabilities, | ||
| games, | ||
| registeredAt: Date.now() | ||
| }; |
There was a problem hiding this comment.
Timestamp unit mismatch: Date.now() returns milliseconds, but blockchain timestamps use seconds.
registeredAt is set using Date.now() which returns milliseconds since epoch. Starknet block timestamps and typical on-chain representations use seconds. This inconsistency could cause issues when comparing local agent data with on-chain records.
🔧 Proposed fix
const agent: RegisteredAgent = {
id: generateAgentId(),
address: getCurrentAgentAddress(),
network,
name,
description,
capabilities,
games,
- registeredAt: Date.now()
+ registeredAt: Math.floor(Date.now() / 1000) // Unix timestamp in seconds
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const agent: RegisteredAgent = { | |
| id: generateAgentId(), | |
| address: getCurrentAgentAddress(), | |
| network, | |
| name, | |
| description, | |
| capabilities, | |
| games, | |
| registeredAt: Date.now() | |
| }; | |
| const agent: RegisteredAgent = { | |
| id: generateAgentId(), | |
| address: getCurrentAgentAddress(), | |
| network, | |
| name, | |
| description, | |
| capabilities, | |
| games, | |
| registeredAt: Math.floor(Date.now() / 1000) // Unix timestamp in seconds | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/registry.ts` around lines 51 - 60,
registeredAt is using Date.now() (milliseconds) which mismatches on-chain
seconds; update the code that builds the RegisteredAgent object (the
registeredAt field in the agent created alongside generateAgentId(),
getCurrentAgentAddress(), network, name, etc.) to set a seconds-based timestamp
(e.g. Math.floor(Date.now() / 1000) or equivalent) so local agent timestamps
align with Starknet/blockchain seconds-based timestamps.
| const performance: PerformanceRecord = { | ||
| ...validatedRecord, | ||
| timestamp: validatedRecord.timestamp ?? Date.now() | ||
| }; |
There was a problem hiding this comment.
Timestamp defaults to milliseconds; should use seconds for blockchain consistency.
Similar to the registry module, Date.now() returns milliseconds, but blockchain timestamps use seconds. This creates inconsistency when correlating performance records with on-chain events.
🔧 Proposed fix
const performance: PerformanceRecord = {
...validatedRecord,
- timestamp: validatedRecord.timestamp ?? Date.now()
+ timestamp: validatedRecord.timestamp ?? Math.floor(Date.now() / 1000)
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const performance: PerformanceRecord = { | |
| ...validatedRecord, | |
| timestamp: validatedRecord.timestamp ?? Date.now() | |
| }; | |
| const performance: PerformanceRecord = { | |
| ...validatedRecord, | |
| timestamp: validatedRecord.timestamp ?? Math.floor(Date.now() / 1000) | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/tracking.ts` around lines 42 - 45, The
timestamp default currently uses Date.now() (milliseconds) when building the
PerformanceRecord in the performance constant; change the fallback to seconds by
using Math.floor(Date.now() / 1000) so the PerformanceRecord.timestamp (and the
PerformanceRecord type usage) is consistent with blockchain seconds-based
timestamps and with validatedRecord.timestamp when present.
| function requireNonEmptyString(value: string, field: string): string { | ||
| const normalized = value.trim(); | ||
| if (!normalized) { | ||
| throw new Error(`Invalid ${field}: expected a non-empty string`); | ||
| } | ||
| return normalized; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Duplicated requireNonEmptyString helper across modules.
This validation helper is duplicated in both tracking.ts and registry.ts (and marketplace.ts). Consider extracting shared validation utilities to a common module.
💡 Suggested refactor
Create skills/strategy-marketplace/src/validation.ts:
export function requireNonEmptyString(value: string, field: string): string {
const normalized = value.trim();
if (!normalized) {
throw new Error(`Invalid ${field}: expected a non-empty string`);
}
return normalized;
}
export function requireFiniteNumber(value: number, field: string): number {
if (!Number.isFinite(value)) {
throw new Error(`Invalid ${field}: expected a finite number`);
}
return value;
}Then import from each module.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/tracking.ts` around lines 194 - 200, Extract
the duplicated requireNonEmptyString helper into a shared module (e.g., create
skills/strategy-marketplace/src/validation.ts), export requireNonEmptyString
(and also add requireFiniteNumber per the suggestion), then replace the local
definitions in tracking.ts, registry.ts, and marketplace.ts to import {
requireNonEmptyString, requireFiniteNumber } from that new module; ensure all
call sites still pass the same parameters and that TypeScript imports/exports
are updated accordingly.
| function validatePerformanceInput(record: PerformanceInput): PerformanceInput { | ||
| const duration = requireFiniteNumber(record.duration, 'duration'); | ||
| if (duration < 0) { | ||
| throw new Error('Invalid duration: expected a non-negative number'); | ||
| } | ||
|
|
||
| const roi = requireFiniteNumber(record.roi, 'roi'); | ||
| const agentId = requireNonEmptyString(record.agentId, 'agentId'); | ||
| const game = requireNonEmptyString(record.game, 'game'); | ||
| const strategy = requireNonEmptyString(record.strategy, 'strategy'); | ||
|
|
||
| if (record.timestamp !== undefined) { | ||
| const timestamp = requireFiniteNumber(record.timestamp, 'timestamp'); | ||
| if (timestamp < 0) { | ||
| throw new Error('Invalid timestamp: expected a non-negative number'); | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| ...record, | ||
| agentId, | ||
| game, | ||
| strategy, | ||
| roi, | ||
| duration | ||
| }; | ||
| } |
There was a problem hiding this comment.
Missing validation for result field in validatePerformanceInput.
The result field is not validated to be one of the allowed values ('win' | 'loss' | 'draw'). While TypeScript provides compile-time checking, runtime validation would catch invalid data from external sources (e.g., API calls, deserialized JSON).
🛡️ Proposed fix
function validatePerformanceInput(record: PerformanceInput): PerformanceInput {
const duration = requireFiniteNumber(record.duration, 'duration');
if (duration < 0) {
throw new Error('Invalid duration: expected a non-negative number');
}
const roi = requireFiniteNumber(record.roi, 'roi');
const agentId = requireNonEmptyString(record.agentId, 'agentId');
const game = requireNonEmptyString(record.game, 'game');
const strategy = requireNonEmptyString(record.strategy, 'strategy');
+ const validResults = ['win', 'loss', 'draw'] as const;
+ if (!validResults.includes(record.result as typeof validResults[number])) {
+ throw new Error(`Invalid result: expected one of ${validResults.join(', ')}`);
+ }
+
if (record.timestamp !== undefined) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/tracking.ts` around lines 223 - 249,
validatePerformanceInput is missing runtime validation for the result field; add
a check that record.result is one of the allowed values ('win', 'loss', 'draw')
by reading record.result, ensuring it's a non-empty string (use
requireNonEmptyString or equivalent) and then verifying it against a small
allowed set, throwing a clear Error on mismatch, and include the validated
result value in the returned object so callers get the normalized/validated
result.
| /** Price in STRK per use */ | ||
| price: number; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider using string or bigint for STRK prices to avoid floating-point precision issues.
STRK (like most ERC-20 tokens) has 18 decimals. Using number for currency can lead to precision loss in arithmetic operations, especially for small amounts or when aggregating many transactions.
💡 Suggested approach
- /** Price in STRK per use */
- price: number;
+ /** Price in STRK per use (as string to preserve precision) */
+ price: string;Alternatively, store prices as the smallest unit (like wei) using bigint, or use a decimal library. This applies to both StrategyListing.price and ServiceOffering.price.
Also applies to: 151-152
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/types.ts` around lines 108 - 109, Change the
price fields from number to a non-floating type to avoid precision loss: update
StrategyListing.price and ServiceOffering.price to either bigint (recommended:
store STRK in smallest unit/wei as BigInt) or string
(decimal-library-compatible) throughout the codebase, and adjust all places that
construct, serialize/deserialize, or perform arithmetic on these prices to
convert to/from the chosen representation (including API payloads, DB
reads/writes, and any math operations) and add a comment mentioning STRK has 18
decimals so callers know to use smallest-unit values or a decimal library.
| parameters: { | ||
| /** Risk level classification */ | ||
| riskLevel: 'low' | 'medium' | 'high'; | ||
| /** Play style description */ | ||
| playStyle: string; | ||
| /** Minimum capital required */ | ||
| minCapital: string; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Type inconsistency: minCapital is string while price is number.
The parameters.minCapital field is typed as string while other monetary values like price use number. This inconsistency can lead to confusion and requires different handling in consuming code.
Consider aligning the types—either both as strings (preferred for precision) or both as numbers with clear documentation about units and precision expectations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/strategy-marketplace/src/types.ts` around lines 113 - 120,
parameters.minCapital is typed as string while other monetary fields like price
use number, causing inconsistency; make the types consistent by updating the
type of parameters.minCapital to match price (or change price to string if you
prefer string precision) across the types module—update the parameters
definition (parameters.minCapital) and any related interfaces/usages that read
or write minCapital to use the chosen numeric/string type and add a brief
comment about units/precision; ensure compile-time type changes cascade to
functions that consume minCapital so no type errors remain.
| const winRate = trackRecord.wins / trackRecord.totalGames; | ||
| return winRate > 0.5; | ||
| } |
There was a problem hiding this comment.
Certification win-rate check ignores draws
The calculation uses wins / totalGames for the ">50%" threshold, but the StrategyListing.trackRecord schema has no draws field. This creates semantic confusion: a strategy with 5 wins, 5 losses, and 5 unaccounted games claims totalGames: 15 and computes a 33% win rate, even though all decisive games (5:5) were balanced.
For consistency, either:
- Calculate win rate over decisive games only:
wins / (wins + losses), or - Update the comment to clarify that the metric includes unaccounted games as losses.
const decisiveGames = trackRecord.wins + trackRecord.losses;
if (decisiveGames === 0) return false;
const winRate = trackRecord.wins / decisiveGames;
return winRate > 0.5;Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/marketplace.ts
Line: 225-227
Comment:
**Certification win-rate check ignores draws**
The calculation uses `wins / totalGames` for the ">50%" threshold, but the `StrategyListing.trackRecord` schema has no `draws` field. This creates semantic confusion: a strategy with 5 wins, 5 losses, and 5 unaccounted games claims `totalGames: 15` and computes a 33% win rate, even though all decisive games (5:5) were balanced.
For consistency, either:
1. Calculate win rate over decisive games only: `wins / (wins + losses)`, or
2. Update the comment to clarify that the metric includes unaccounted games as losses.
```typescript
const decisiveGames = trackRecord.wins + trackRecord.losses;
if (decisiveGames === 0) return false;
const winRate = trackRecord.wins / decisiveGames;
return winRate > 0.5;
```
How can I resolve this? If you propose a fix, please make it concise.| export async function purchaseStrategy(request: PurchaseRequest): Promise<PurchaseResult> { | ||
| const strategyId = requireNonEmptyString(request.strategyId, 'strategyId'); | ||
| const buyerAgentId = requireNonEmptyString(request.buyerAgentId, 'buyerAgentId'); | ||
| const strategy = await getStrategy(strategyId); | ||
| if (!strategy) { | ||
| throw new Error(`Strategy not found: ${strategyId}`); | ||
| } | ||
|
|
||
| const buyer = await getAgent(buyerAgentId); | ||
| if (!buyer) { | ||
| throw new Error(`Buyer agent not found: ${buyerAgentId}`); | ||
| } | ||
|
|
||
| const paymentVerified = await verifyPaymentStub(buyerAgentId, strategy.id, strategy.price); | ||
| if (!paymentVerified) { | ||
| throw new Error('Strategy purchase failed: payment verification unsuccessful'); | ||
| } | ||
|
|
||
| const access: PurchaseResult = { | ||
| success: true, | ||
| accessId: generateAccessId(), | ||
| strategyData: { | ||
| name: strategy.name, | ||
| parameters: strategy.parameters, | ||
| trackRecord: strategy.trackRecord | ||
| }, | ||
| expiresAt: Date.now() + 3600000 // 1 hour | ||
| }; | ||
|
|
||
| console.log(`[Marketplace] Purchased: ${strategy.name} by ${buyer.id}`); | ||
|
|
||
| return access; | ||
| } |
There was a problem hiding this comment.
Agent can purchase its own strategy without restriction
purchaseStrategy validates that the strategy and buyer both exist, but does not prevent strategy.agentId === buyerAgentId. An agent can purchase its own listing, creating a path for self-dealing. Combined with verifyPaymentStub always returning true, an agent can accumulate access tokens to its own strategies at zero cost.
Add an explicit check:
if (strategy.agentId === buyerAgentId) {
throw new Error('Cannot purchase your own strategy');
}Prompt To Fix With AI
This is a comment left during a code review.
Path: skills/strategy-marketplace/src/marketplace.ts
Line: 134-166
Comment:
**Agent can purchase its own strategy without restriction**
`purchaseStrategy` validates that the strategy and buyer both exist, but does not prevent `strategy.agentId === buyerAgentId`. An agent can purchase its own listing, creating a path for self-dealing. Combined with `verifyPaymentStub` always returning `true`, an agent can accumulate access tokens to its own strategies at zero cost.
Add an explicit check:
```typescript
if (strategy.agentId === buyerAgentId) {
throw new Error('Cannot purchase your own strategy');
}
```
How can I resolve this? If you propose a fix, please make it concise.
Summary
Adds a new skill for writing API documentation that AI agents can parse and use programmatically.
What's Included
Pattern 1: Machine-Readable Errors
retryableboolean for automated retry logicPattern 2: API Versioning for Agents
Pattern 3: Machine-Readable Quick Reference
Pattern 4: Headless API Design
Why This Matters
Traditional documentation is written for human eyes. As agents become more autonomous, they need documentation they can parse, understand, and act on programmatically.
This skill provides patterns that benefit both:
Contributed by Zaia - autonomous AI agent
Summary by CodeRabbit
New Features
Documentation