Repository navigation
Troubleshooting and FAQ
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document is a practical troubleshooting and FAQ guide for Sigvara’s ecosystem. It focuses on agent registration, score computation, slash disputes, integration issues, performance tuning, security incident response, diagnostics, known limitations, and planned improvements. The guidance maps directly to the protocol contracts, the oracle implementation, and the SDK usage patterns documented in the repository.
Sigvara consists of:
- On-chain registries: identity, staking, reputation, and optional oracle bonding.
- Off-chain components: an oracle that computes scores from payment-backed evidence and watchdog flags, plus supporting utilities such as backoff, caching, and metrics.
- SDK and examples: TypeScript helpers for agent-to-agent authentication, gating, DID resolution, and registration flows.
graph TB
subgraph "On-chain"
ID["SigvaraIdentity"]
ST["SigvaraStaking"]
REP["SigvaraReputation"]
end
subgraph "Off-chain"
OR["Oracle"]
SDK["TypeScript SDK"]
CACHE["Response Cache"]
end
OR --> REP
OR --> ID
ST --> ID
ST --> REP
SDK --> REP
SDK --> ID
OR --> CACHE
Diagram sources
Section sources
- SigvaraIdentity: anchors agent identities, Ed25519 keys, operator control, status transitions, and two-step operator transfer.
- SigvaraStaking: manages bonds, unbonding, slashing initiation/dispute/execution, and proceeds distribution.
- SigvaraReputation: stores computed scores, enforces challenge windows, maturity, evidence roots, and bonded-oracle checks.
- Oracle scoring: pure functions compute six factors; chain helpers provide RPC resilience, slot-race handling, and fee-gating.
- Response cache: LRU cache with revision-based invalidation for expensive evidence responses.
Section sources
- SigvaraIdentity.sol:22-160
- SigvaraStaking.sol:31-218
- SigvaraReputation.sol:14-75
- scoring.js
- chain.js:59-186
- response-cache.js:1-34
The system follows an optimistic scoring model:
- The oracle proposes a score with an evidence root.
- A challenge window allows the committee to reject bad proposals.
- Finalization is permissionless after the window.
- Slashing can zero reputation and mark agents terminal.
sequenceDiagram
participant UC as "User / Counterparty"
participant OR as "Oracle"
participant REP as "SigvaraReputation"
participant CM as "Committee"
UC->>OR : "Attestation + settlement tx"
OR->>REP : "proposeReputation(didHash, data, evidenceRoot)"
REP-->>OR : "ScoreProposed"
Note over REP : "Challenge window open"
alt "Committee rejects during window"
CM->>REP : "rejectReputation(didHash)"
REP-->>CM : "ScoreRejected"
else "Window elapses unchallenged"
UC->>REP : "finalizeReputation(didHash)"
REP-->>UC : "ReputationUpdated(totalScore)"
end
Diagram sources
Section sources
Common symptoms:
- Registration reverts with signature or key errors.
- Agent remains PendingBond after deposit.
- Operator cannot rotate key or transfer ownership.
Resolution steps:
- Verify the agent address signed the registration digest returned by the registry.
- The digest must be unsigned before signing; wallets apply EIP-191 automatically.
- Ensure the signer is the agent address itself (EOA or ERC-1271).
- Confirm the agent is registered and not already present under the same didHash.
- Deposit stake to reach minimumStake to transition from PendingBond to Active.
- If key compromise occurred:
- Suspend the agent immediately.
- Rotate the Ed25519 public key.
- Reinstate only after rebonding if needed.
- For operator transfer:
- Offer transfer, then accept from the new operator.
- Transfers are blocked while slash is pending.
flowchart TD
Start(["Registration Entry"]) --> Digest["Compute registrationDigest()"]
Digest --> Sign["Agent signs digest off-chain"]
Sign --> Register["Call registerAgent(agentAddress, pubKey, signature)"]
Register --> Status{"Status = PendingBond?"}
Status --> |Yes| Stake["Deposit stake >= minimumStake"]
Stake --> Activate["updateStatus(PendingBond -> Active)"]
Status --> |No| Error["AlreadyRegistered or BadSignature"]
Activate --> End(["Active"])
Error --> End
Diagram sources
Section sources
Common symptoms:
- Scores do not finalize.
- Committee rejects proposed scores.
- Evidence verification fails.
- Maturity feels too slow or too fast.
Resolution steps:
- Check factor caps: each factor must not exceed its maximum.
- Ensure the agent is scorable:
- Registered and not slashed.
- Bonded according to the stake view.
- Validate evidence root:
- Rebuild Merkle proof for each payment leaf.
- Compare against stored evidenceRoots.
- Use chain timestamps for time-sensitive logic to avoid host clock skew.
- Adjust maturity rate through governance if necessary; it cannot be set to zero, and on
mainnot above 100 points a day. - On
main, finalizing also asks whether the proposer could still make the proposal: if it has lostORACLE_ROLEor its operator standing,finalizeReputationrevertsProposerNotAuthorizedand a replacement proposal (the primary's next epoch, or a checker'sproposeIfEmpty) takes its place. The Arc testnet contracts do not check the proposer.
flowchart TD
Start(["Score Proposal"]) --> ValidateFactors["Validate factor caps"]
ValidateFactors --> Scorable{"Agent scorable?"}
Scorable --> |No| Reject["Revert: NotRegistered/Slashed/NotBonded"]
Scorable --> |Yes| StorePending["Store PendingScore + evidenceRoot"]
StorePending --> Window{"Challenge window active?"}
Window --> |Reject| Cancel["Committee rejects proposal"]
Window --> |Finalize| Mature["Set matured anchor and timestamp"]
Mature --> End(["Live score"])
Diagram sources
Section sources
Common symptoms:
- Agent stuck in Suspended state.
- Slash proposal never executed or canceled.
- Dispute freeze persists beyond expected period.
Resolution steps:
- Initiate slash:
- Committee calls initiateSlash with victim and evidence hash.
- Agent becomes Suspended immediately.
- On
mainit revertsSlashCooldownActiveif a proposal for the agent was dropped less than one challenge period ago.
- Dispute:
- Operator calls disputeSlash within the challenge deadline.
- Proposal moves to Disputed; stake remains frozen.
- Resolution:
- On
mainthe admin resolves, not the committee: uphold executes the slash, but only after the challenge deadline fixed when the slash was filed (ChallengePeriodActivebefore then); drop cancels at any time and reinstates if bonded. The admin can alsovetoSlasha pending or disputed proposal. The Arc testnet contracts have worked this way since 26 October 2026. Onmainan uphold is also refused once the dispute can be expired (DisputeResolutionExpired); the testnet takes that at its next upgrade. - If unresolved, anyone may expireDispute after the resolution period (14 days).
- On
- Execution:
- Anyone may executeSlash after the challenge period without dispute, as long as the reporter still holds the committee role. On
main, a pending slash that nobody executes can be dropped by anyone withexpireSlash14 days after its deadline, so execute promptly. - Distribution: 50% burn, 25% victim, 25% reporter.
- Identity marked Slashed; reputation zeroed.
- Anyone may executeSlash after the challenge period without dispute, as long as the reporter still holds the committee role. On
sequenceDiagram
participant V as "Victim"
participant C as "Committee"
participant S as "SigvaraStaking"
participant I as "SigvaraIdentity"
participant R as "SigvaraReputation"
V->>C : "Report agent + evidence"
C->>S : "initiateSlash(didHash, victim, evidenceHash)"
S->>I : "updateStatus(Suspended)"
Note over S : "Challenge period begins"
alt "Operator disputes"
Op->>S : "disputeSlash(didHash)"
Admin->>S : "resolveDispute(didHash, uphold/drop)"
else "Undisputed"
Any->>S : "executeSlash(didHash)"
S->>I : "updateStatus(Slashed)"
S->>R : "zeroReputation(didHash)"
end
Diagram sources
Section sources
Common symptoms:
- SDK gate rejects agents unexpectedly.
- Agent-to-agent authentication fails.
- On-chain consumers cannot read scores reliably.
Resolution steps:
- Gate checks:
- Verify proof validity, replay protection, active status, and threshold.
- Use a shared NonceStore behind load balancers.
- Agent-to-agent auth:
- Verifier issues a challenge payload including DID, nonce, and timestamp.
- Prover signs with Ed25519 private key.
- Verifier resolves public key from chain and verifies signature and threshold.
- On-chain reads:
- Use getTotalScore/meetsThreshold for decisions.
- Handle provider failures gracefully; consider retries and backoff.
sequenceDiagram
participant A as "Agent A"
participant B as "Agent B"
participant ID as "SigvaraIdentity"
participant REP as "SigvaraReputation"
B->>A : "Challenge : SIGVARA-VERIFY : {DID} : {nonce} : {timestamp}"
A->>A : "Sign payload with Ed25519"
A->>B : "{did, signature}"
B->>ID : "getIdentity(didHash)"
ID-->>B : "{pubKey, status}"
B->>REP : "meetsThreshold(didHash, threshold)"
REP-->>B : "true/false"
alt "Valid and meets threshold"
B-->>A : "Action permitted"
else "Invalid or below threshold"
B-->>A : "Rejected"
end
Diagram sources
Section sources
Key dependencies:
- SigvaraStaking depends on SigvaraIdentity for status and operator checks.
- SigvaraReputation depends on SigvaraIdentity for scorable checks and optionally on an operator bond registry.
- Oracle chain helpers depend on ethers contracts and implement backoff, slot-race detection, and rate-limit classification.
classDiagram
class SigvaraIdentity {
+registerAgent()
+rotatePublicKey()
+updateStatus()
+offerOperatorTransfer()
+acceptOperatorTransfer()
}
class SigvaraStaking {
+depositStake()
+initiateWithdrawal()
+claimWithdrawal()
+initiateSlash()
+disputeSlash()
+resolveDispute()
+expireDispute()
+expireSlash()
+cancelSlash()
+vetoSlash()
+executeSlash()
}
class SigvaraReputation {
+proposeReputation()
+proposeIfEmpty()
+finalizeReputation()
+rejectReputation()
+zeroReputation()
+getTotalScore()
+verifyEvidence()
}
class ChainHelpers {
+readWithBackoff()
+isSlotTaken()
+isRateLimited()
+proposeScore()
+finalizeScore()
+getPendingScore()
+getTotalScore()
}
SigvaraStaking --> SigvaraIdentity : "status checks"
SigvaraReputation --> SigvaraIdentity : "scorable checks"
ChainHelpers --> SigvaraReputation : "propose/finalize"
ChainHelpers --> SigvaraIdentity : "identity queries"
Diagram sources
- SigvaraIdentity.sol:295-468
- SigvaraStaking.sol:320-776
- SigvaraReputation.sol:369-769
- chain.js:702-863
Section sources
- SigvaraIdentity.sol:295-468
- SigvaraStaking.sol:320-776
- SigvaraReputation.sol:369-769
- chain.js:702-863
Gas optimization tips:
- Batch operations where possible; avoid redundant reads in hot paths.
- Prefer paged accessors for large operator agent lists.
- Use view calls locally when safe (e.g., didHash derivation verified once per process).
- Avoid unnecessary token approvals; check allowance before depositing.
Query performance:
- Use readWithBackoff for transient RPC failures; distinguish genuine reverts from node errors.
- Chunk log scans to respect provider limits and checkpoint progress frequently.
- Cache stake view contract instance to reduce repeated lookups.
Caching strategies:
- Use response cache for expensive endpoints like evidence generation.
- Size cache by serialized bytes; evict least-recently-used entries.
- Invalidate via revision tokens rather than explicit invalidation calls.
Section sources
Symptoms:
- BadRegistrationSignature or AlreadyRegistered.
- PendingBond never becomes Active.
- Cannot rotate key or transfer operator.
Checklist:
- Confirm agent signed the registration digest returned by the registry.
- Ensure the agent address is not already registered.
- Deposit stake at least equal to minimumStake to activate.
- For key compromise: suspend, rotate key, reinstate after rebonding.
- For operator transfer: offer then accept; transfers blocked during slash pending.
Errors to watch:
- BadRegistrationSignature
- AlreadyRegistered
- InsufficientCollateral
- TransferWhileSlashPending
- SlashSuspensionLocked
Section sources
- SigvaraIdentity.sol:295-321
- SigvaraIdentity.sol:328-397
- SigvaraIdentity.sol:410-468
- SigvaraStaking.sol:320-363
Symptoms:
- proposeReputation reverts with factor out-of-range.
- finalizeReputation reverts with NoScorePending or ChallengeWindowActive.
- Evidence verification returns false.
Checklist:
- Validate all six factors against their caps.
- Ensure agent is scorable (registered, not slashed, bonded).
- Recompute evidence root and verify leaf proofs.
- Use chain timestamps for timing checks.
- Governance-adjust maturity rate if needed; zero is rejected, and on
mainso is anything above 100 points a day. - On
main,finalizeReputationrevertsProposerNotAuthorizedfor a proposal whose proposer has lost its standing; a replacement proposal supersedes it.
Errors to watch:
- ScoreOutOfRange
- NoScorePending
- ChallengeWindowActive
- ProposerNotAuthorized (on
main) - IdentityRegistryNotSet
- StakeViewNotSet
- AgentNotRegistered
- AgentSlashed
- AgentNotBonded
Section sources
Symptoms:
- Slot taken repeatedly.
- Rate-limited writes.
- Operator standing denied.
Checklist:
- Distinguish slot-taken from real failures using isSlotTaken.
- Classify rate limiting using isRateLimited; do not retry writes.
- Check operatorStanding at startup; ensure wallet is admitted and bonded.
- Use proposeIfEmpty for checker mode to avoid overwriting primary proposals. On
mainit also replaces a pending proposal whose proposer has lost its authority; the Arc testnet contracts revert for any pending proposal. - Tell a transaction the oracle would not sign (a fee above
MAX_FEE_GWEIor a worst-case cost aboveMAX_TX_COST) or never saw mined from the contract refusing it: they are counted insigvara_oracle_tx_refused_total{reason}, and the cause is the RPC. - If the oracle will not start, read the first lines of its log. It names every numeric setting it cannot use, a wrong
ORACLE_MODE, a key that is not 64 hex characters (the value is never printed), a non-loopback bind with no write credential, a state file it cannot use, and an RPC on a chain other thanEXPECTED_CHAIN_ID.
Errors to watch:
- ScoreAlreadyPending
- OracleNotBonded
- ProposerNotAuthorized (on
main) - AlreadyCharged (the oracle counts it as paid)
- Provider throttling (-32005, 429)
Section sources
Symptoms:
- Agent remains Suspended.
- Slash proposal never executed or canceled.
- Dispute freeze persists.
Checklist:
- Verify challenge deadline and dispute deadlines.
- The admin must resolve disputed slashes; otherwise expireDispute after period.
- ExecuteSlash requires undisputed window to have elapsed, and the reporter to still hold the committee role (
ReporterNotAuthorizedotherwise). - On
main, a pending slash that nobody executes or cancels can be expired withexpireSlashonce 14 days have passed since its deadline. - After execution, identity becomes Slashed and reputation is zeroed.
Errors to watch:
- ChallengePeriodActive
- ChallengePeriodExpired
- SlashAlreadyPending
- SlashNotDisputed
- DisputeResolutionActive
- DisputeResolutionExpired (on
main) - SlashCooldownActive (on
main) - ExecutionPeriodActive (on
main)
Section sources
Key procedures:
- Key compromise:
- Immediately suspend the agent.
- Rotate Ed25519 key.
- Reinstate after rebonding if required.
- Slash dispute:
- The admin upholds or drops; expired disputes can be cleared.
- Emergency:
- Follow the security policy and report privately.
- Coordinate disclosure after fix availability.
Section sources
This guide consolidates common failure modes across registration, scoring, slashing, and integration, with concrete resolutions mapped to the protocol contracts and oracle implementation. Use the diagnostic helpers for RPC resilience, classify slot races and throttling correctly, and rely on evidence roots and maturity mechanics to maintain trustworthiness. For ongoing issues, consult the security policy and coordinate responsibly.
Conceptual questions:
- What does the reputation score represent?
- It is a normalized, capped sum of six factors derived from payment-backed attestations, community flags, external trust, and counterparty standing. Only bonded agents are scored.
- How does staking work?
- Operators deposit stake to back agents. Bonds enable slashing; withdrawals enter an unbonding queue still subject to slash sweeps.
- What is the protocol economics model?
- Slashed stake is partially burned, with portions awarded to victims and reporters. Fees may gate epoch scoring when configured.
Operational questions:
- Why is my score not finalizing?
- Check factor caps, scorable status, evidence root, and challenge window timing.
- Why does the gate reject my agent?
- Verify proof validity, replay protection, active status, and threshold.
- How do I recover from a compromised key?
- Suspend, rotate key, reinstate after rebonding.
Section sources
- Agent Registration and Lifecycle
- Contract Overview and Architecture
- Economic Security Model and Incentives
- Evidence Verification and Merkle Proofs
- Key Management and Rotation
- Maturity Mechanism and Score Release
- Proposal Workflow and Challenge System
- Score Storage and Data Model
- SigvaraIdentity Contract
- SigvaraOracleBond Contract
- SigvaraReputation Contract
- SigvaraStaking Contract
- Slashing Lifecycle and Dispute Resolution
- Stake Management Functions
- Status Management and Control
- Token and Fee Contracts
- Unbonding Period and Withdrawal Security
- Anti-Manipulation and Security Measures
- Community Flag Processing
- Evidence Sources and Verification
- External Trust Integration
- Merkle Proof System
- Oracle Score Computation
- Payment-Backed Attestations
- Scoring Model and Formulas
- Agent Creation and Key Management
- Agent Operations
- Agent Registration Workflow
- Challenge-Response Authentication
- Gate Access Control
- Integration Patterns and Examples
- SDK Overview and Setup
- Verifier Functions