Synthèse automatique
Réalise un audit de sécurité structuré du lecteur .pex et du décompilateur Papyrus ainsi que du lexer/parseur .psc, en ciblant les bornes sur entrées non fiables et les risques d'AST silencieusement erroné.
Points forts
- Définit un périmètre précis pour crates/pex et crates/papyrus, avec les fichiers et modules concernés.
- Distingue clairement les défauts de sûreté du décompilateur des simples erreurs de documentation.
- Prévoit des règles de sévérité adaptées aux entrées non fiables, aux débordements de pile/tas et aux AST incorrects acceptés par les reconnaisseurs.
- Ordonne une approche delta-first avec vérification des garde-fous et exécution des tests ciblés.
Limites
- Très couplé au dépôt ByroRedux, à ses chemins, ses documents d'audit et ses conventions internes.
- Ne couvre ni les reconnaisseurs, ni le runtime, ni les autres parseurs comme hkx ou ESM VMAD.
- Suppose l'accès à l'historique GitHub, aux corpus et aux outils d'instrumentation du projet.
À utiliser pour auditer les frontends Papyrus de ByroRedux lors d'une revue de sécurité ou de robustesse sur des données .pex/.psc non fiables.
À éviter pour un audit général du pipeline de script, d'autres formats de fichiers, ou un projet sans les crates et documents ByroRedux référencés.
Analyse de sécurité
PrudenceNo exfiltration, obfuscation, or curl|sh-style payloads. The skill is a read-only analysis workflow: it runs the project's own tests/examples, reads git history and GitHub issues, writes a report under docs/audits, and cleans up its own /tmp scratch dir. Power is used legitimately (build/test tooling, network read via gh, a fixed-path rm -rf), so this lands at 'caution' rather than 'safe' or 'risky'.
- •Skill assumes shell/CLI execution (cargo test, cargo run --example, git log, gh issue list) despite declaring no allowed-tools, so the required privilege set is not made explicit.
- •Phase 4 runs `rm -rf /tmp/audit/papyrus` — destructive, but scoped to a fixed temp path the skill itself creates via `mkdir -p`; no variable substitution or wildcard, so blast radius is minimal.
- •`gh issue list --repo ...` performs outbound network calls to GitHub and relies on the user's stored gh credentials (token read implicitly by the gh CLI, not handled or exfiltrated by the skill).
- •`cargo run --release -p byroredux-pex --example pex_corpus_smoke` processes untrusted .pex/.psc corpora; the skill's whole purpose is hardening against hostile input, and it explicitly treats panics/OOM as findings, which is defensive rather than risky.
- •Uses shell tooling (mkdir, git, gh, cargo test/run, rm) throughout — legitimate for an audit workflow but requires bash and network access (gh issue list, cargo) to execute as written
- •Phase 4 runs `rm -rf /tmp/audit/papyrus`; the target is the skill's own scratch directory created in Phase 1, so the blast radius is confined, but blanket `rm -rf` is worth flagging for a reviewer
- •Runs example binaries compiled from the repo (`pex_corpus_smoke`, `r5_extract_pex_ba2`) against game-archive inputs — expected for the task, no exfiltration or obfuscation
- •No instructions embedded in the content attempt to alter the auditor's role or assessment; treated the whole document as data
Exemples
/audit-papyrus --focus pex-reader --depth deepAudit the Papyrus decompiler passes for cases where copy propagation or boolean collapse could produce a wrong AST that a recognizer accepts, and report HIGH findings with file and line evidence./audit-papyrus --focus papyrus-lexer-parser --depth shallow — check .psc lexer and Pratt parser depth caps, allocation bounds, and panic paths reachable from untrusted source.description: "Deep audit of the Papyrus compiler frontends — .pex reader + 5-phase decompiler (Champollion port, crates/pex) and the .psc lexer/Pratt parser (crates/papyrus): untrusted-input bounds, decompiler soundness, depth caps" argument-hint: "--focus <dimensions> --depth shallow|deep"
Papyrus Frontend Audit (crates/pex + crates/papyrus)
Read .claude/commands/_audit-common.md and .claude/commands/_audit-severity.md for shared protocol.
Audit the two frontends that turn Papyrus bytes into the shared byroredux_papyrus::ast::Script:
untrusted .pex bytecode → decode (crates/pex) → 5-phase decompiler, and .psc source → lexer + Pratt
parser (crates/papyrus). Both feed the recognizer chain in /audit-scripting (which owns
translate_pex's clean-None contract and the panic net); this skill owns everything up to the AST.
Highest bug-density area of the scripting domain (untrusted input + five tree-rewriting passes).
Findings here are silent wrong-AST (a recognizer then matches it → wrong ECS behavior on vanilla
content) or process aborts (OOM / stack overflow — catch_unwind cannot recover either, so a panic net
is no substitute for a bound).
Architecture: Orchestrator; each dimension is a Task agent (max 3 concurrent).
Scope
crates/pex/src/:reader.rs,opcode.rs,model.rs,lib.rs(parse,PexError,string_byte_budget),call_sites.rs(Pex::call_sites, the extender-preflight scan — consumed by/audit-scriptingDim 7),decompile/{mod,cfg,lift,boolean,control_flow,lower,node,event_names}.rs.crates/papyrus/src/:token.rs,lexer.rs,ast.rs,span.rs,error.rs,lib.rs,parser/{mod,expr,stmt,script}.rs.- Instruments:
crates/pex/examples/pex_corpus_smoke.rs(decompiles every.pexin real archives; the source of the decompile-rate claim),pex_dump_fn.rs(raw-bytecode disassembly of one failing function),pex_corpus_shapes.rs+docs/r5/corpus-shape-survey.txt,crates/bsa/examples/r5_extract_pex_ba2.rs(corpus extractor). - Ground truth: crate docstrings (
crates/pex/src/lib.rs,decompile/mod.rs),docs/engine/{papyrus-parser, m47-2-design}.md("no opcode semantics guessed"). Reference decompiler: Champollion (OPCODES,PscCoder::writeStates); UESP Papyrus Assembly spec for operand order. - Not here: hkx (
/audit-parsers), ESM VMAD decode (/audit-esm), recognizers/runtime (/audit-scripting).
Parameters / Extra Fields / Severity
--focus default all 4 · --depth shallow (bounds + depth-cap contracts) | deep (trace each pass's tree
rewrite). Finding fields: Dimension: PEX Reader | Decompiler CFG & Lift | Decompiler Boolean/Control-Flow/
Lower | Papyrus Lexer & Parser · Untrusted-Input: Yes | No (Yes for any path consuming raw .pex/.psc).
Escalations over _audit-severity.md: panic / OOB / unbounded alloc or recursion reachable from untrusted
bytes → HIGH (CRITICAL if memory-unsafe — the transmute in opcode.rs); decompiler emits a wrong AST
that a recognizer accepts, or copy-propagation / boolean-collapse folds into the wrong consumer → HIGH
(silent, all-game blast radius); doc rot → LOW.
Phase 1: Setup
mkdir -p /tmp/audit/papyrus; dedup gh issue list --repo matiaszanolli/ByroRedux --limit 300 --json number,title,state,labels > /tmp/audit/papyrus/issues.json;
read the newest docs/audits/AUDIT_SCRIPTING_*.md (Dims 1-4 findings; pre-split reports use the old
8-dimension numbering) and docs/engine/m47-2-design.md §"Frontends in detail"/"Risks & mitigations" to
separate designed declines from defects. Run cargo test -p byroredux-pex -p byroredux-papyrus.
Delta-first: git log --since=<last report> --format='%h %cs %s' -- crates/pex crates/papyrus — these crates
are quiet between some passes (and busy in others — M47.2 churned lower.rs and the parser's script items);
if there are none, re-verify the guards below rather than re-reading source.
Phase 2: Dimensions
Dimension 1: .pex Reader & Opcode Decode (untrusted input — every finding is Untrusted-Input: Yes)
Paths: crates/pex/src/{reader,opcode,model,lib,call_sites}.rs
First step: cargo test -p byroredux-pex (then re-read any guard named below that did not run)
take(n)is the single bounds gate (checked_add+<= len→UnexpectedEof). No read path may indexself.data[..]ortry_into().unwrap()a short slice. Guard:every_prefix_of_every_wire_valid_ sample_is_rejected(exhaustive-prefix over five builders: Skyrim LE/BE, extender-dependent BE, Starfield guards, and #4474'sbuild_sample_full_coverage— FO4 debug-info skips, getter/setter bodies, non-emptystruct_infos,Value::Float). A new reader branch no sample reaches is the gap to look for.- Allocation is bounded by something other than a wire count: var-arg count
n(up toi32::MAX) must not feedVec::with_capacity(grow bypush;hostile_vararg_count_errors_instead_of_ooming); otherwith_capacity(count)sites areu16-capped;u32flags/sizes are never capacities. String copies are charged againststring_byte_budget=max(64 × file size, 16 MiB)in bothreader.rsandcall_sites.rs(ScanBudget; #4317 — a ~330 KB wire-valid file once exhausted 8 GB and aborted). Any new owned copy of a table string (a new model field, a new scan) must be charged; guardsstring_copies_past_the_budget_are_refused,call_site_copies_are_bounded_by_the_string_budget. OpCode::from_u8transmute(unsafe, memory-safety-critical):MAX_OPCODE == 51equals last discriminant + 1, enum#[repr(u8)]with contiguous0..=50, guard is>=; a compile-timeconst _: () = assert!(OpCode::TryLockGuards as u8 == MAX_OPCODE - 1)backs it (#4475). Pins:discriminants_match_on_disk_order,from_u8_round_trips_and_rejects_oob,metadata_matches_champollion{,_full_table}(verify they cover every discriminant, not spot values).arg_counttable drives operand consumption: a wrong row desyncs the whole stream silently. Spot-check var-arg opcodes (callmethod/callparent/callstatic/guard ops) and high-arity rows (array_findstruct5,array_getallmatchingstructs6) against Champollion/UESP.string_index→.get(idx)/BadStringIndex(neverself.strings[idx]);value()accepts tags 0..=5,Integersign-reinterprets; endianness from magic (0xFA57C0DELE /0xDEC057FABE) with the provisional LE innew()never leaking into a multibyte read; Skyrim-vs-FO4+ field gating (is_skyrim():const_flag,struct_infos, property-group/struct-order tables; Starfield-onlyguards) reads in FileReader order and the consume-and-discard skips match the writer's byte counts.read_binaryis all-or-Err(no partialPex);call_sitesstops with a diagnostic when its budget is exhausted rather than truncating silently. Output:/tmp/audit/papyrus/dim_1.md
Dimension 2: Decompiler — CFG & Opcode→Node Lift (copy-propagation is the AST-correctness core)
Paths: crates/pex/src/decompile/{cfg,lift,node}.rs
First step: cargo test -p byroredux-pex -- decompile::cfg decompile::lift
- Jump targets:
checked_targetaccepts0 <= ip+offset <= count(inclusive —countis the exit anchor); non-integer offset →BadJumpOffset, OOB →JumpOutOfRange, non-{ident,bool,int} condition →BadJumpCondition.CodeBlock::split(at)is never called withat == 0(underflow). jmpf/jmptpolarity:jmpfjumps when FALSE (true-edge = fall-through); a flip inverts everyIf(forward_jmpf_builds_an_if_diamond,forward_jmpf_with_unconditional_backedge_builds_a_loop, andbackward_jmpt_builds_a_loop_edge— a trueJmpTpin since #4476; it was a misnamedJmpFtest before).rebuild_expression: a temp-producing node folds into the single immediately-next live consumer (count_constant_id: 0 → advance, 1 → inline, >1 →ExpressionRebuildFailed); folding into a non-adjacent consumer reorders side effects. It runs over a linked live-index chain, not restart-at-0/Vec::remove(O(n²), #2024 —rebuild_expression_is_linear_up_to_the_wire_format_ceiling).is_finalvsis_temp_varasymmetry (::tempprefix,_varsuffix) is a deliberate Champollion port — unifying them is a regression.replace_constant_id'sdebug_assert!(slot.is_none())is debug-only: a release >1-match would silently drop the producer.- Depth is memoized on
Node(Node::depth,recompute_depth) and checked at every fold againstMAX_EXPR_DEPTH(= the papyrus parser constant), so repeated re-folds by the boolean/control-flow passes cannot reset the ledger (the SIGABRT class); guardsa_temp_chain_past_the_depth_cap_is_declined_not_aborted/..._inside_the_depth_cap_still_folds. Any new in-place tree mutation must callrecompute_depth. create_node:Castdowngrades toCopyonly when source isNone, same-typed identifiers, or::nonevar(case-insensitive) — a wrong downgrade turns a narrowing cast into an identity copy. Operand order forCallMethod/CallStatic/CallParent(result/object/method indices) is what recognizers key on (SetStage,GetStageDone); cross-check UESP.id_ofon a literal →ExpectedIdentifier, neverunwrap()outside a checked branch. Bodyless/native functions decompile to an empty body. Output:/tmp/audit/papyrus/dim_2.md
Dimension 3: Decompiler — Boolean, Control-Flow, Lower & the Corpus Instruments
Paths: crates/pex/src/decompile/{boolean,control_flow,lower,event_names,mod}.rs, crates/pex/examples/pex_corpus_smoke.rs
First step: cargo test -p byroredux-pex -- decompile::; with game data: cargo run --release -p byroredux-pex --example pex_corpus_smoke -- <Skyrim - Misc.bsa> <Fallout4 - Misc.ba2>
- Pass order is load-bearing:
lower::decompile_bodyruns cfg → lift →rebuild_boolean_operators→reconstruct→lower_body; the boolean pass precedes control-flow so&&/||chains collapse first. control_flow.rs: shape classification (While:last.next == current; If:last.next == exit; If/Else; jmpt inversion negates + swaps edges). A conditional-predecessorlast(||shape the boolean pass should have collapsed) fails closed (ControlFlowFailed, #1732;conditional_predecessor_fails_closed) — a fix that resumes past the block drops statements. The module doc's "advanced past" wording is stale (#4115 open, verified 2026-10-15).- Three bookkept Champollion departures —
boolean.rs's two (plus a third, newer guard below), andlower.rs'sis→ object-typedCast(#4477,an_is_opcode_lowers_to_an_object_typed_cast; recognizer-irrelevant only while no consumer keys on it). For theboolean.rstwo — adjudicate benign-or-bug, evidence = corpus rate + fidelity gate, not speculation: (1) no debug-line guard (a same-named temp on a fall-through edge could be falsely collapsed into a fabricated&&/||); (2) termination guard (only re-process on a real merge — infinite loop hangs the decompiler).&&true edge falls through,||false edge; operand must recompute the same condition variable; prec&&=7/||=8;take_operandleaves no danglingNone. Private-edge guard (944d0299e): a fold deletes the operand block (and a non-exit rejoin), so it now declines unlessincoming(operand) == 1and, for an interior rejoin,incoming(rejoin) == 2— a sharedreturnepilogue that an early-exitjmpalso targets left a dangling edge and failedreconstruct(the last two corpus decompile failures: FO4StimBoxScript, FO76Debug.TraceLog; corpus now 100% on all four games). Pinsor_whose_rejoin_is_a_shared_epilogue_is_left_uncollapsed,and_whose_rejoin_is_a_shared_epilogue_is_left_uncollapsed. A new fold that deletes a block without an in-edge count is the regression. - Recursion:
MAX_REBUILD_DEPTH = 1024incontrol_flow.rs(boolean.rsderives it — not restated); both rebuilds returnRecursionLimit(rebuild_rejects_excessive_recursion_depthexists in both files). It andMAX_EXPR_DEPTH(256) compose additively (~1,280) and independent edits erode the margin (#4113 open, verified 2026-10-15) — check any change to either constant. lower.rstotality:lower_expr/lower_stmtnever panic on anyNodeKind; intentional lossy lowerings matter only if a recognizer keys on the lost info: statement-shaped node as sub-expression →NoneLit(should be unreachable),is→Cast,lower_binary_opdefault arm →Eq(a real unknown op silently becomes==).StructCreateis no longer lossy: it lowers toExpr::NewStruct(FO4new S, the shape the.pscparser now emits too). Locals:lower_local_declsprepends one bareVarDeclper non-::local ahead of the body (0c6fe4d34— without it every Champollion fragment prologue read as an assignment to an undeclared name and the #5638 fragment guard declined it;user_locals_are_declared_ahead_of_the_body_and_temporaries_are_not).- Script assembly: FO4+
struct_infoslower toScriptItem::Structitems first (members keep their stored defaults;pex_corpus_smoke's expected-item-count addsstruct_infos.len()); synthetic::variables dropped; variable and auto-property defaults lower toinitial_valueviadefault_literal(the backing variable's stored default); the object'sconditional/hidden/defaultuser flags (bit indices named by the file's own user-flag table, resolved ONCE perPexbyUserFlagMasks::from_pex— #5683d8b1d333c, the old per-variable has_user_flag rescan was O(F×V), ~18 s on an 852 KB hostile file,a_hostile_user_flag_table_decompiles_in_linear_time;flag_index < 32guards the shift on untrusted bytes) lower into the sameScriptFlagsthe.pscheader parses, a variable'sconditionalintois_conditional(#5398ce90b481c,object_user_flags_lower_into_script_flags) and a property'sconst/mandatory/hidden/conditionalintoPropertyFlags(#5685f7afb0e07,property_user_flags_lower_into_property_flags); script scope = the empty-named state's functions; every named state → aStateitem; exactly one (the first case-insensitiveis_auto_statematch againstauto_state_name) isis_auto(#4473,case_colliding_state_names_mark_exactly_one_auto) — keying scope on the auto match inverted 983 vanilla scripts (#4319;named_auto_state_stays_an_auto_state_and_the_empty_state_is_script_scope). Event iff (on-prefixed ANDis_event_name) OR::remote_-prefixed;EVENT_NAMESis a sorted lowercase union binary-searched (list_is_sorted_for_binary_search); a missing engine event demotes a handler to a function. The list is a documented superset of Champollion's frozenEventNames.hpp: 12 real engine events it omits (OnAttach,OnStoryClearLocation, ten Starfield) are hand-added in sorted position from a base-class corpus census (#44710611cd116;the_census_engine_events_classify_as_events, which also keeps vanilla typos likeoncelldetatchout) — an addition needs the same census evidence, not a guess. - The decompile-rate claim measures robustness, not fidelity. Verify
pex_corpus_smokecountsErrand panics as failures and tallies afterdecompile_script. Its shape check must not share an implementation rule with the code under test — the #3017 check anddecompile_scriptshared the wrong auto-state rule and both agreed on 983 mis-assembled scripts. Fidelity evidence is the.psc-vs-.pexgate (owned by/audit-scriptingDim 1:recognizes_da10_and_reproduces_hand_builder+da10_pex_reproduces_hand_builder_byte_for_byte), not the corpus rate. Output:/tmp/audit/papyrus/dim_3.md
Dimension 4: .psc Lexer & Pratt Parser (untrusted: .psc files and console/debug text)
Paths: crates/papyrus/src/{token,lexer,ast,error,lib}.rs, crates/papyrus/src/parser/{mod,expr,stmt,script}.rs
First step: cargo test -p byroredux-papyrus -- depth chain the_two_parser_depth_caps_stay_equal
- Depth caps (stack overflow and AST
Droprecursion):MAX_EXPR_DEPTH = 256(expr.rs) andMAX_STMT_DEPTH = 256(stmt.rs), bothpub, equality pinned bythe_two_parser_depth_caps_stay_equal; downstreamMAX_CONDITIONAL_DEPTHandlift.rs's cap alias them. The Pratt loop chargesexpr_depthfor each node a postfix/binary chain wraps (#4320 — the cap once counted only recursive calls, soa.a.a…of ~0.4 MB overflowed on Drop) and restores on every exit including error paths (long_postfix_and_binary_chains_hit_the_depth_cap,realistic_chains_still_parse_and_release_their_depth,depth_resets_between_top_level_calls). All recursive expression entry funnels throughparse_expr_bp. - Newline is a terminator in the Pratt loop: the loop uses
peek_raw(), not the newline-skippingpeek()(#4321 — a line opening with(was glued to the previous statement, a silent wrong AST). Explicit\continuations are joined bylexer::preprocess; an operator ending a line still continues. Verify every otherpeek()on a statement boundary: #4472 (six sites, viacheck_raw) and #4763 (seven more —Extends, variable/function/group flags, property and local initializers) moved construct-continuation decisions to the raw stream, each pinned by an*_on_the_next_line_*test inscript.rsplussingle_line_forms_of_the_4763_sites_still_parse. Remainingpeek()/check()sites should sit behind an explicitskip_newlines()or a bracket-bounded list.expect()/expect_ident()still skip newlines, so a keyword's mandatory operand goes throughexpect_same_line/expect_raw/expect_ident_raw(parser/mod.rs; #5021,3b7ffa670): declaration names, theExtendstarget, the(after a function name,StateafterAuto, the If/ElseIf/While condition start, andNew's type and[— #5331fd5aa4ead,parse_new_expr; the[is optional only for anObjecttype, where a same-linenew Sis FO4'sExpr::NewStruct— pinned bya_mandatory_operand_on_the_next_line_is_an_error,auto_on_its_own_line_does_not_make_an_auto_state,extends_with_its_target_on_the_next_line_sets_no_parent,single_line_forms_of_the_5021_sites_still_parse. Only closing keywords may keep the newline-skippingexpect; a new declaration keyword that uses it is the regression. - Statement termination (#5322
a5c3f2428):expect_eol(parser/mod.rs) used to accept ANY token after a statement, so a tail the Pratt loop stopped at re-parsed as a new statement (If f is Actorbecame a truthiness test plus a fabricatedVarDecl) with zero errors. It now records a recoveredUnexpectedTokenfor anything but Newline/EOF/DocComment and skips to line end viaskip_to_line_end, which leaves block terminators (EndIf,Else*,End*) unconsumed so a gluedx = 1 EndIfstill closes its block (glued_statement_tail_is_an_error_and_not_a_statement;EndStruct/EndGroupstay too, #54443efa1c024,glued_struct_and_group_terminators_stay_for_their_container);parse_expr(debug console, offline preflight) ends inrequire_input_end(parse_expr_rejects_trailing_tokens). FO4isis a keyword with anExpr::Istype-test node at cast precedence (test_is_type_test); downstream exhaustive matches treat it as transparent to the operand (the.pexside still lowersOpCode::Isto an object-typedCast, so the two frontends do NOT yet share one shape). - Doc comments and FO4 names (
e96d687ec): Papyrus puts an item's{…}doc on the line AFTER its header, sotake_trailing_doc(parser/mod.rs) consumes one right after each header'sexpect_eol(script header, property, group, struct + member, function/event; #5325 — a bodied function's doc once became its first "statement" and the function was dropped). Script name,Extendstarget andImportare qualified idents (DLC01:Foo), and an event name may be the remote formSender.Eventkept dotted in the name so a name-matching consumer declines it (#5328). Pinsa_doc_comment_after_a_bodied_function_header_documents_it,namespaced_script_name_parent_and_import_keep_every_segment. - Precedence/associativity:
BinaryOp::precedenceOr=1, And=2, comparisons=3, Add/Sub/StrCat=4, Mul/Div/Mod=5, unary=6, cast=7/postfix=8 (PREC_*inexpr.rs); left-assoc hinges onop_prec <= min_bp → break. (Bethesda's inverted CTDA OR/AND precedence is a condition-evaluation concern in/audit-scriptingDim 3 —.pscoperators are standard.) preprocess:\+\n/\r\n/lone\relided (2/3/2 bytes) with exactOffsetMapcounts (a wrong count drifts every later span); a trailing\at EOF is emitted, not swallowed. Keywords areignore(case)(logos 0.16 dropped ascii_case,15a6b1d2d— Unicode folding, which differs only for the few non-ASCII letters that fold onto ASCII, e.g. U+017F, U+212A, invalid Papyrus either way) and win over theIdentregex. CK flags matched contextually stay out of the lexer:Default(script header) andCollapsed(group) are identifiers checked in their flag position (#5398ce90b481c,default_and_collapsed_remain_identifiers) — expressions accept onlyToken::Ident, so promoting either to a keyword breaks every variable of that name. Lone CR is a line terminator and CRLF oneNewline(bare_cr_is_a_newline_and_crlf_is_one_newline, #4479 — a CR-only file once lexed to zero newlines); a;line comment likewise stops at the first\ror\n(line_comment_ends_at_a_bare_cr, #5019a75c7dc33— it once searched only\n, swallowing a CR-only file to EOF with zero errors);0xand exponent shapes route throughMalformedNumberto aLexError, not an adjacent token pair.- Recovery:
parse_scriptreturnsOk((Script, Vec<ParseError>))for partial success andErronly for fatal;skip_to_next_linealways consumes ≥1 token (no infinite loop); callers needing strict-fail checkresult.1.is_empty(). Nounwrap()onstr::parseof a malformed-but-lexable literal. Output:/tmp/audit/papyrus/dim_4.md
Phase 3: Merge
Combine /tmp/audit/papyrus/dim_*.md into docs/audits/AUDIT_PAPYRUS_<TODAY>.md: Executive Summary
(findings by severity; untrusted-input robustness verdict — can a hostile .pex/.psc panic, OOB, OOM,
or stack-overflow the cell loader / console — must be NO; decompile-rate verdict — re-measured, and what
it does and does not prove) · Decompiler Soundness Matrix (reader / cfg / lift+copy-prop / boolean /
control-flow / lower / .psc parser × bounds-safe, terminates, total, fidelity-tested; the three Champollion
departures adjudicated) · Findings (severity order, deduplicated). Cross-audit: recognizer/runtime →
/audit-scripting; .pex bytes reaching the extender preflight → /audit-scripting Dim 7.
Phase 4: Cleanup
rm -rf /tmp/audit/papyrus; tell the user the report is ready; suggest
/audit-publish docs/audits/AUDIT_PAPYRUS_<TODAY>.md (domain label scripting).
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/papyrus-frontend-audit-pex-psc-mvda88sk/download' --output '.skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk/SKILL.md.part' && mv '.skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk/SKILL.md.part' '.skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Le fichier ne fournit pas un en-tête name/description exploitable pour cette procédure native. Le téléchargement reste disponible pour lecture ; utilisez le mode manuel ci-dessous.
Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/papyrus-frontend-audit-pex-psc-mvda88sk/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Sécurité AMM DeFi
Securite
Checklist de sécurité pour les contrats Solidity AMM, pools de liquidité et flux de swap. Couvre réentrance, attaques par donation, manipulation d'oracles, etc.
Créateur de règles Semgrep
Securite
Crée des règles Semgrep personnalisées pour détecter des vulnérabilités de sécurité, des motifs de bugs et des motifs de code. Inclut une méthodologie de test en premier, le support du mode taint et des étapes de validation. Utile pour construire des détections d'analyse statique ciblées.
Revue barre d'outils développement
Securite
Règles de sécurité pour la barre d'outils de développement, le client PostHog et les feature flags. À utiliser lors de la revue de modifications des composants dev-tools et connexes.