ia-pinescript — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited ia-pinescript (Agent Skill) and scored it 91/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Verify before implementing: For Pine Script version-specific syntax or new built-in functions, look up current official docs before writing code. Prefer Context7 (query-docs) when available. Otherwise use available web tools to read the TradingView Pine Script docs for the script's version. TradingView updates Pine Script frequently and training data may be stale.
isBull = close > open
barColor = isBull ? color.green : color.redplot(condition ? value : na)barstate.isconfirmed when signals require the chart bar's closing values. It does not establish that requested higher-timeframe values are confirmed; inspect request.security() offsets and lookahead separately.Check the current platform limits before sizing a script: 64 plot counts (one call can consume several); up to 500 line, box, or label IDs each and 100 polyline IDs; 40 unique request.*() calls, or 64 on Ultimate; 100,000 compiled tokens. History buffers, requested intrabars, and chart history have distinct limits; there is no general 500-bar request.security() history limit.
xloc.bar_index reach at most 9,999 bars into the past and 500 into the future; for anything older, switch the drawing to xloc.bar_time and pass a timestamp (a time value without xloc.bar_time is treated as a future bar index and errors)max_*_count declaration parameter and cap growth with a rolling buffer: push each object, then line.delete(arr.shift()) after the intended line count is exceeded. The default display count is approximately 50 per drawing type.request.security() returning [close, high, low] instead of 3 separate callsarray.new<type>(size) instead of push-and-resizeta.rsi() in global scope on every bar. Short-circuit signal predicates using those stored results; see Pine v6 lazy evaluation.for item in myArray (or for [i, item] in myArray) instead of for i = 0 to array.size(...) - 1; both forms use updated collection sizes on later iterations.for...in, resize arrays or matrices only with the changing iteration bounds in mind. To add or remove map entries, iterate a map.keys() snapshot or a map.copy() while modifying the original. Avoid directly initializing var/varip with a loop result: the loop stops after its first iteration. Declare first and assign with :=, or return the loop result from a function. See the Pine v6 loop rules.type Trade with float entry, int startBar, plus method functions, stored in one array<Trade>. Parallel arrays (entries, startBars, ...) desync on any missed push/remove and every operation must be repeated per array; one typed array keeps each object's fields togetherUse Pine Logs through log.info(), log.warning(), and log.error(), plus these visual checks:
label.new(bar_index, high, str.tostring(myVar)) to inspect values; cap retained labels explicitly.table.new() with barstate.islast for real-time variable dashboardif input.bool(false, "Debug") for local debug code; keep plot calls global.value[1] refers to the preceding bar and does not detect revisions to an earlier calculation.strategy.* functions: strategy.wintrades, strategy.losstrades, strategy.grossprofit var float maxEquity = strategy.equity
maxEquity := math.max(maxEquity, strategy.equity)
dd = maxEquity > 0 ? (maxEquity - strategy.equity) / maxEquity * 100 : nat, score prediction[horizon] against the now-realized outcome, such as close > close[horizon], excluding warmup bars. Positive offsets reference the past, never future bars; see history referencing.color.from_gradient() for trend strength coloringsize.small for intraday, size.normal for daily+input.*(..., active = condition) greys out an input when its controlling toggle is off (e.g. a smoothing length only editable while "Use smoothing" is checked), which is clearer than a tooltip saying "ignored unless..."indicator()/strategy()@version, @description, @param tagstooltip="Line 1" + "\n" + "Line 2"input() make the script untestable across instruments.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.