Skip to content

feat: preserve richer IDL metadata in stack specs#116

Merged
adiman9 merged 6 commits into
mainfrom
codama-types
Jun 18, 2026
Merged

feat: preserve richer IDL metadata in stack specs#116
adiman9 merged 6 commits into
mainfrom
codama-types

Conversation

@adiman9

@adiman9 adiman9 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
arete-docs Ready Ready Preview, Comment Jun 18, 2026 12:47am

Request Review

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extends the IDL metadata preserved in Arete stack specs: it adds Codama PDA resolution (inline and link-resolved), fielded enum variants (struct and tuple payload shapes), optional account tracking, and the isSigner: "either" flag. The AST version is bumped to 0.0.2 with backward-compatible deserialization of 0.0.1 specs.

  • Codama PDA resolution: codama_account_pda resolves pdaValueNode default values into IdlPda seeds (constant, account-ref, and arg-ref), with tracing::warn for every degradation path and new tests covering link-nodes, inline nodes, and optional accounts.
  • Fielded enum support: CodamaEnumVariant gains struct_ and tuple payload fields; codama_enum_variant_to_idl converts all three shapes; the old blanket error on fielded variants is replaced by a discriminator-index consistency check.
  • Versioning / compatibility: COMPATIBLE_AST_VERSIONS = ["0.0.1"] lets the interpreter load older specs directly with serde defaults, normalising the version field on read; VersionedStackSpec::V2 / VersionedStreamSpec::V2 are added alongside V1.

Confidence Score: 5/5

Safe to merge; all changes are additive, old specs deserialize unchanged, and every new PDA degradation path logs a warning and returns None rather than producing wrong data.

The core IDL parsing changes are well-tested with four new integration-level tests covering PDA link nodes, inline PDAs, optional accounts, fielded enums, and the isSigner 'either' flag. The backward-compat strategy (COMPATIBLE_AST_VERSIONS + skip_serializing_if on the new fields) ensures existing stack.json files continue to load and round-trip correctly. The sign-extension logic in codama_constant_seed_bytes was verified to handle positive, negative, and overflow cases correctly. The two findings raised are both non-blocking nits.

arete-idl/src/parse.rs is the largest change and deserves the closest read; in particular codama_constant_seed_bytes numeric encoding and the codama_account_pda degradation paths.

Important Files Changed

Filename Overview
arete-idl/src/parse.rs Core of the PR: adds PDA resolution, fielded-enum parsing, isSigner 'either' handling, and changes numberValueNode from u64 to i64. Sign-extension logic in codama_constant_seed_bytes is carefully validated; degradation paths are all logged.
arete-idl/src/types.rs Adds IdlEnumVariantField (Named/Tuple) and fields vec to IdlEnumVariant with skip_serializing_if for backward compat. Also fixes anchor discriminator to snake_case instruction name before hashing.
arete-idl/src/snapshot.rs Mirrors types.rs: IdlEnumVariantFieldSnapshot with serde(untagged). Disambiguation is safe because IdlFieldSnapshot requires both 'name' and 'type' keys, which no IdlTypeSnapshot variant has.
arete-macros/src/ast/versioned.rs Adds COMPATIBLE_AST_VERSIONS and normalises ast_version on load. V2 variants added to VersionedStackSpec/VersionedStreamSpec.
interpreter/src/versioned.rs Mirrors arete-macros versioned.rs consistently.
arete-macros/src/stream_spec/idl_spec.rs Reorders manual PDA extraction before instruction parsing; also filters pdas! macro items from generated module output.
arete-macros/src/ast/writer.rs Extracts convert_enum_variant helpers; removes per-instruction error list duplication.
stacks/ore/.arete/OreStream.stack.json Generated: ore PDA entries now have full seed definitions; automation account resolution upgraded to pdaRef.
rust/arete-a4-sdk/tests/auth_lifecycle.rs Increases token expiry and refresh timeout to reduce CI flakiness from clock skew.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Caller
    participant parse as parse_idl_content
    participant root as codama_root_to_idl_spec
    participant ix as codama_instruction_to_idl
    participant pda as codama_account_pda
    participant seed as codama_constant_seed_bytes

    Caller->>parse: parse_idl_content(json)
    parse->>parse: try serde IdlSpec
    alt not IdlSpec
        parse->>parse: try serde CodamaRoot
        parse->>root: "codama_root_to_idl_spec(&root)"
        root->>root: build pda_defs HashMap
        loop each instruction
            root->>ix: "codama_instruction_to_idl(instr, &pda_defs)"
            loop each account
                ix->>pda: codama_account_pda(account, pda_defs)
                alt pdaValueNode with pdaLinkNode
                    pda->>pda: lookup pda_defs[name]
                else inline pdaNode
                    pda->>pda: use inline seeds
                end
                loop each constantPdaSeedNode
                    pda->>seed: codama_constant_seed_bytes(value, seed_type)
                    seed-->>pda: "Vec<u8> or None"
                end
                pda-->>ix: Some(IdlPda) or None
            end
            ix-->>root: IdlInstruction
        end
        root-->>parse: IdlSpec
    end
    parse-->>Caller: "Result<IdlSpec, String>"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Caller
    participant parse as parse_idl_content
    participant root as codama_root_to_idl_spec
    participant ix as codama_instruction_to_idl
    participant pda as codama_account_pda
    participant seed as codama_constant_seed_bytes

    Caller->>parse: parse_idl_content(json)
    parse->>parse: try serde IdlSpec
    alt not IdlSpec
        parse->>parse: try serde CodamaRoot
        parse->>root: "codama_root_to_idl_spec(&root)"
        root->>root: build pda_defs HashMap
        loop each instruction
            root->>ix: "codama_instruction_to_idl(instr, &pda_defs)"
            loop each account
                ix->>pda: codama_account_pda(account, pda_defs)
                alt pdaValueNode with pdaLinkNode
                    pda->>pda: lookup pda_defs[name]
                else inline pdaNode
                    pda->>pda: use inline seeds
                end
                loop each constantPdaSeedNode
                    pda->>seed: codama_constant_seed_bytes(value, seed_type)
                    seed-->>pda: "Vec<u8> or None"
                end
                pda-->>ix: Some(IdlPda) or None
            end
            ix-->>root: IdlInstruction
        end
        root-->>parse: IdlSpec
    end
    parse-->>Caller: "Result<IdlSpec, String>"
Loading

Reviews (4): Last reviewed commit: "fix(arete-a4-sdk): stabilize auth_lifecy..." | Re-trigger Greptile

Comment thread arete-idl/src/parse.rs Outdated
Comment thread arete-idl/src/parse.rs
Comment thread arete-idl/src/parse.rs
adiman9 added 3 commits June 18, 2026 01:27
CodamaValueNode::Number was u64, so any Codama IDL carrying a negative
constant seed value (e.g. {"number":-1} for an i8 seed) hit a hard
serde_json deserialization error that aborted the entire instruction
parse — the #[serde(other)] arm only catches unknown kind strings, not
a failed inner deserialization.

Switch the field to i64 (covers all signed/unsigned widths a single
numeric PDA-seed literal can carry) and make codama_constant_seed_bytes
sign-extension-aware: the truncation guard now accepts valid negative
values like -1_i8 (0xFF sign-extended) and rejects genuine overflow,
while widening (e.g. i64 literal into an i128 slot) sign-extends
instead of zero-padding.

SteelDiscriminant.value stays u64; the call site now uses
u64::try_from with a clear error for negatives, preserving the
non-negative discriminant invariant previously enforced by the hard
serde failure.
CodamaSignerFlag::Tag caught any string that wasn't true/false, but
is_either() only recognised "either" — any other tag value (e.g. a
future Codama extension like "readonly") resolved to is_signer=false
with no doc annotation and no error, silently producing incorrect
signer behaviour.

Add unknown_tag() returning any tag other than "either", and emit a
doc annotation (signer: "<tag>" unrecognised isSigner tag; treated as
non-signer) so callers can see why an account was treated as a
non-signer instead of getting incorrect behaviour with no indication.
codama_account_pda returned None for a range of conditions (unknown
pdaLinkNode name, unsupported seed kind, numeric type mismatch, missing
binding) — all silently degrading the account to UserProvided. An
incorrectly-structured Codama IDL would produce a stack spec that
looked valid but omitted PDA derivation data, with no way to tell why a
known PDA was not being resolved without inspecting source code.

Add tracing::debug! for the benign no-PDA-default path and tracing::warn!
at each genuine resolution failure (unknown link, missing binding,
unsupported seed kind, unencodable constant), keyed on account and seed
names so a mis-structured IDL is diagnosable from logs.
The first token's expiry sat only 1s past the refresh buffer, so the
`set_token` "is expiring" check tripped whenever a loaded CI runner
introduced >1s between the token endpoint issuing the token and the
SDK validating it. Bump the first expiry to 75s (15s headroom) and
the refresh-wait timeout to 20s to match the resulting ~15s refresh
delay.
@adiman9 adiman9 merged commit 5c42827 into main Jun 18, 2026
11 checks passed
@adiman9 adiman9 deleted the codama-types branch June 18, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant