T09 · Insecure Skill Coding Practices
- Location
references/shared/cross_model_verification.md:453- Finding
Gemini API Key Exposed in Request URL
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent academic workflow orchestrator, but it warrants Review because optional cross-model features and process records can expose manuscripts, dialogue, and API credentials if users enable them without tight controls.
Install only if you want a long-running academic pipeline that reads and records substantial manuscript and conversation context. Keep cross-model verification disabled unless you are comfortable sending the named content to the selected provider, require HTTPS for compatible endpoints, use restricted dedicated API keys, and review generated process records before sharing them.
references/shared/cross_model_verification.md:453Gemini API Key Exposed in Request URL
references/shared/cross_model_verification.md:493Unrestricted Compatible-Provider URL Permits Plaintext Credential and Manuscript Transmission
Referenced artifact was not completely inspected
k instruction MUST be: "Before executing, fully read the applicable rule file (`./SKILL.md` of the target skill, or `./references/<role_file>.md` for a role age
Referenced artifact was not completely inspected
| `references/shared/handoff_schemas.md` | Cross-skill data contracts: 9 schemas for all inter-stage handoff artifacts |
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
**You audit; you do not arbitrate.** Your job is to produce evidence-bound verdicts (SUPPORTED / UNSUPPORTED / AMBIGUOUS / RETRIEVAL_FAILED + a specific `defect_stage`) plus uncited / drift / constraint-violation surfaces. You do not decide whether the paper passes — that is the formatter's job, driven by your annotation severity tier.
**Experiment-backed claims are NOT yours to judge.** A claim whose manifest entry carries `planned_experiment_ids[]` is backed by the scholar's own experiment provenance, not by a retrieved reference. Its faithfulness verdict (`experiment_alignment_results[]` with verdict ∈ {ALIGNED, OVERSTATED, NOT_SUPPORTED_BY_PROVENANCE, PROVENANCE_INSUFFICIENT}) is computed by the **`integrity_verification_agent` at the Stage 2.5/4.5 gate** (mirroring the figure-fidelity pattern), NOT here. You must (a) NOT emit any `experiment_alignment_results[]` row, and (b) NOT misroute an experiment-only sentence into `claim_audit_results[]` or `uncited_assertions[]` just because it has no `<!--ref:slug-->` marker — see the D4-c carve-out below and the Manifest cross-reference precedence rule. A **mixed-evidence** claim (manifest entry carries BOTH `planned_refs` AND `planned_experiment_ids`) DOES get your normal citation-path treatment for its cited portion (a `claim_audit_results[]` row); the experiment path is the integrity agent's separate row, and the gate combines them worst-verdict-wins. Mixed-evidence is the ONE case where the same claim legitimately appears on both sides.
External motivation: Zhao et al. arXiv:2605.07723 (2026-05) documents 146,932 hallucinated citations across 2025 arXiv / bioRxiv / SSRN / PMC, naming **L3 (claim faithfulness)** as the load-bearing unsolved problem. v3.7.3 closed the locator channel (per-citation anchor markers); v3.8 closes the audit channel (judge-evaluated alignment against the retrieved reference text).
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
- For ambiguous judgments: prefer AMBIGUOUS + LOW-WARN advisory over forcing UNSUPPORTED. AMBIGUOUS is a valid outcome; coercing it to UNSUPPORTED inflates the false-positive rate on the calibration gold set.
- For retrieval failures: distinguish stable access restriction (`failed` — paywall) from transient infrastructure outage (`audit_tool_failure` — judge timeout / API 5xx / network error) via the rationale tag (INV-14). Do NOT collapse them.
- DO NOT simulate any retrieval step. DO NOT claim to have read a paper the retrieval layer did not actually return. If retrieval failed, emit RETRIEVAL_FAILED with the correct `ref_retrieval_method` and let the gate surface it.
- DO NOT mutate `<!--ref:slug-->` or `<!--anchor:...-->` markers. The Cite-Time Provenance Finalizer already resolved them upstream; you read, never write. The v3.6.7 partial-inversion discipline keeps the agent narrative-side and the finalizer audit-side separate — preserve it here by NOT reading entry frontmatter to discover ref or anchor candidates.
## Differences from integrity_verification_agent
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
- **`claim_intent_manifests[]`** — pre-commitment baseline emitted by synthesis_agent / draft_writer_agent / report_compiler_agent before prose generation (see "Claim Intent Manifest Emission (v3.8)" sibling sections on those agents). Used by §4 step 5 manifest set-diff.
- **`literature_corpus[]`** — for retrieval.
- **Resolved citation markers** post Cite-Time Provenance Finalizer — every in-text citation carries both `<!--ref:slug-->` (v3.7.1 two-layer) and `<!--anchor:<kind>:<value>-->` (v3.7.3 three-layer). `anchor_kind=none` rows should already have been gate-refused by v3.7.3 R-L3-1-A; this agent's defense-in-depth row INV-6 surfaces any that slipped through.
- **Draft sentence stream (uncited)** — the Stage 4 draft sentence list, with each sentence carrying its `section_path` and optional `adjacent_text` (the surrounding 1-3 clauses for context). Two routing surfaces (Step 13 R4 codex P1 #2):
- **`all_uncited_sentences` (FULL set)** — every uncited sentence in the draft, regardless of D4-c trigger token presence. This is the input to the §4 step 5 stream (d) `constraint_violations[]` HIGH-WARN path. A manifest negative constraint like "MUST NOT use causal language" can be violated by a sentence ("The program caused improvement") that the D4-c detector filters OUT (no quantifier, no empirical trigger). Routing constraint judging through the D4-c subset would silently drop those HIGH-WARN cases.
- **`uncited_sentences` (D4-c subset)** — the output of `detect_uncited_assertions` per spec §4 step 6 (D4-c three-condition token rule). This is the input to the §4 step 6 `uncited_assertions[]` LOW-WARN advisory emission only.
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
**Unified judge prompt** (canonical):
<!-- JUDGE-PROMPT-CANONICAL-START: 自动校验脚本(移植版未附带,以文字规则为准) hashes the text between these markers; any change here MUST bump JUDGE_PROMPT_VERSION in 自动校验脚本(移植版未附带,以文字规则为准) so stale judge-cache entries are not served against the new prompt. -->
> Given this claim from a paper draft, this excerpt from the cited reference, AND the author's declared negative constraints, return ONE verdict.
>
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
**Unified judge prompt** (canonical):
<!-- JUDGE-PROMPT-CANONICAL-START: 自动校验脚本(移植版未附带,以文字规则为准) hashes the text between these markers; any change here MUST bump JUDGE_PROMPT_VERSION in 自动校验脚本(移植版未附带,以文字规则为准) so stale judge-cache entries are not served against the new prompt. -->
> Given this claim from a paper draft, this excerpt from the cited reference, AND the author's declared negative constraints, return ONE verdict.
>
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.
- **Scope**: score the collaboration *pattern*; the paper, research, and AI output belong to other agents.
- **Session-bounded**: the rubric is per-pipeline; produce no cross-session leaderboard or global scoreboard.
- **Describe, don't judge**: speak about the observable pattern, not the person's character or ability.
- **Offer, don't prescribe**: phrase next-stage suggestions as options ("you could try X") rather than duties ("you should X"). The rubric is descriptive.
---
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.
## Interaction with existing features
- **Collaboration Depth Observer (v3.5.0):** fires on FULL/SLIM as before. Observer output is included in the checkpoint notification regardless of reset state. Observer state does NOT carry across resets; each fresh session observes only its own stage.
- **Compliance agent (v3.4.0):** `compliance_history[]` remains append-only and is consumed from the passport on resume. No change to Schema 12.
- **Sprint contract (v3.6.2):** reviewer sprint contracts load from the passport on resume (Phase 1 paper-content-blind stage remains valid across the reset boundary because the contract + paper metadata are carried in the passport).
- **Socratic reading probe (v3.5.1):** reading probe fires at most once per session. Across a reset boundary, the probe counter resets — the next session may fire its own probe. This is by design: each session is its own Socratic unit.
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.
## Interaction with existing features
- **Collaboration Depth Observer (v3.5.0):** fires on FULL/SLIM as before. Observer output is included in the checkpoint notification regardless of reset state. Observer state does NOT carry across resets; each fresh session observes only its own stage.
- **Compliance agent (v3.4.0):** `compliance_history[]` remains append-only and is consumed from the passport on resume. No change to Schema 12.
- **Sprint contract (v3.6.2):** reviewer sprint contracts load from the passport on resume (Phase 1 paper-content-blind stage remains valid across the reset boundary because the contract + paper metadata are carried in the passport).
- **Socratic reading probe (v3.5.1):** reading probe fires at most once per session. Across a reset boundary, the probe counter resets — the next session may fire its own probe. This is by design: each session is its own Socratic unit.
The document declares Stage 2.5 and 4.5 integrity checks as mandatory and non-skippable, yet the exception flow explicitly allows users to continue to the next stage with a 'partially unverified' warning after repeated failures. That creates a policy bypass: an attacker or careless user can push unverifiable or fabricated citations through a workflow whose main trust control is integrity verification.
The skill authorizes sending raw dialogue turns, including unpublished research and private reasoning, to an external provider under cross-model mode. Although a consent gate is mentioned, the capability materially expands data exfiltration surface beyond core orchestration and creates confidentiality, privacy, and IP leakage risk if enabled, misconfigured, or socially engineered.
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
**The audit agent receives.**
- All in-text citations with their resolved `<!--ref:slug ...-->` + `<!--anchor:...-->` marker pairs (post-finalizer)
- The `claim_intent_manifests[]` aggregate from the writing-stage agents (per spec §3.2 + the v3.8 "Claim Intent Manifest Emission" sibling sections on `synthesis_agent` / `draft_writer_agent` / `report_compiler_agent`)
- The `literature_corpus[]` aggregate (retrieval input)
- **PDF read-integrity sidecars.** The orchestrator runs `python 自动校验脚本(移植版未附带,以文字规则为准) <pdf> --output <sidecar>.json` ONCE per locally-read PDF in the `literature_corpus[]` **at Stage 1 corpus intake — NOT only when this audit gate is active**. This audit is opt-in and default OFF while the three emitters run earlier at Stages 2/4; if the preflight only ran here, default-mode runs would reach R-L3-1-D with no sidecar in context and valid local-PDF page citations would be forced to `anchor:none` and gate-refused. Running at intake (every local PDF, not an attempted pre-filter by which anchors it sourced — anchor→file provenance is not recorded anywhere the orchestrator can read, and an extra preflight run is cheap and deterministic) means the sidecars ride the emitters' context from the first dispatch onward, so R-L3-1-D holds at emission, and this gate simply consumes the same sidecars when active. This is the layer that CAN run Bash (Bucket A writers cannot), so enforcement sits here, upstream of the writers. Pass the sidecars keyed by `ref_slug` (verdict `PASS`/`FAIL`/`UNAVAILABLE` + file `sha256` + declared/enumerated/reader page counts; the hash is confirmatory, and the natural join key later): `PASS` licenses page-scoped retrieval; `FAIL`/`UNAVAILABLE`/missing routes the row to the `[pdf_read_integrity_unverified]` advisory path. When the audit runs through the executable pipeline, pass the same map as `run_audit_pipeline(pdf_preflight_sidecars=...)` so the tag is applied on the executable path too, cache hits included. **Freshness:** before
...[truncated 25 chars]
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
- The Material Passport `literature_corpus[]` entries (each carries `citation_key`, `source_acquired`, `source_verified_against_original`).
- The peer-file `<session>_human_read_log.yaml` (path computed as `<passport-path-parent>/<passport-stem>_human_read_log.yaml` per §3.6 round-5 R5-003 amend) — records `USER_ATTESTED_READ` declarations. It is user attestation, not independent proof of reading or comprehension.
**Join semantics:** for each `<!--ref:slug-->` marker, apply the v3.7.3 anchor precedence before consulting reading state: a missing marker, `kind=none`, an out-of-enum kind, or an empty value routes to MED-WARN-NO-LOCATOR and never reaches the read matrix. For a valid `{quote,page,section,paragraph}` anchor, dereference `slug` against `literature_corpus[]` to obtain `(source_acquired, source_verified_against_original)`, then pass the read-log, `citation_key`, and that exact anchor to 自动校验脚本(移植版未附带,以文字规则为准)。 The resolver strictly validates the current closed ledger, `USER_ATTESTED_READ` type/scope pairing, RFC3339-UTC event order, and anchor enum before returning a closed state, `ok_eligible`, and `finalizer_disposition`; only `state=covered` is eligible for `ok`. Its JSON is a transient routing decision, not an audit receipt: never persist or replay it, and recompute it from the current ledger and anchor on every pass. The `literature_corpus[]` schema is NOT mutated (per §3.6 firm rule #1: derived keys are not stored).
**4-cell resolution matrix (from spec §3.3 lines 174-179):**
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
| `ok` or `LOW-WARN` | `semantic_scholar_unmatched: true` only | append `CONTAMINATED-UNMATCHED` |
| `ok` or `LOW-WARN` | both fields true | append `CONTAMINATED-PREPRINT+UNMATCHED` |
Example: `<!--ref:smith2024 LOW-WARN CONTAMINATED-PREPRINT-->` or `<!--ref:smith2024 ok CONTAMINATED-PREPRINT+UNMATCHED-->`.
**Advisory by default.** The contamination annotation SUFFIX does not change the gate decision: `ok CONTAMINATED-...` passes the formatter hard-gate and `LOW-WARN CONTAMINATED-...` is eligible for user attestation via <slug> --scope <level>` exactly like plain LOW-WARN; promotion still requires deterministic anchor coverage. The suffix surfaces the signal so the user can verify the source or remove the citation. (v3.10 adds an OPT-IN terminal channel: when the passport's `terminal_policies.contamination_triangulation` is `strict` / `strict_articles_only`, a k=3 signal additionally co-emits a `TERMINAL-BLOCK` token that the formatter refuses on — see § Cite-Time Provenance Finalizer — v3.10 extension. The advisory suffix itself stays advisory; the terminal block is a separate, additional token.)
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
Example markers:
- `<!--ref:smith2024 LOW-WARN CONTAMINATED-COVERAGE-NOISE-->` — single-index unmatched, k_max ≥ 2.
- `<!--ref:smith2024 ok CONTAMINATED-PARTIAL-UNMATCH-->` — two-of-three (or three-of-four) unmatched.
- `<!--ref:smith2024 LOW-WARN CONTAMINATED-TRIANGULATION-UNMATCHED-->` — all three indexes unmatched.
- `<!--ref:smith2024 LOW-WARN CONTAMINATED-ARXIV-UNMATCHED-->` — arxiv-only (k_max=1) unmatched.
- `<!--ref:smith2024 LOW-WARN CONTAMINATED-QUADRANGULATION-UNMATCHED-->` — all four indexes unmatched.
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
Example (strict, ID-keyed false): `<!--ref:bogus2024 ok TERMINAL-BLOCK severity=HIGH-BLOCK policy=citation_existence reason=lookup_verified_false mode=strict policy_hash=citation_existence.strict-->` — the marker carries the base-status (`ok`) and the terminal token; there is no citation-existence advisory suffix between them (contrast contamination, whose `CONTAMINATED-*` suffix DOES occupy the advisory slot).
**Gating output = the existing Stage-5 formatter hard gate (C-V6(d)).** ARS has no separate "ready-for-review" state machine; the equivalent is the existing Stage-4→5 boundary where the finalizer runs and `formatter_agent` then refuses. Under `strict`, the appended `TERMINAL-BLOCK severity=HIGH-BLOCK` token is refused by `formatter_agent`'s generic rule-11 (any unresolved `severity=HIGH-BLOCK` inside a `<!--ref:...-->` marker), so the draft cannot reach final formatted output — i.e. a draft with a provably-bogus citation cannot reach the human-review deliverable. This gate is therefore symmetric with `contamination_triangulation == strict`: same terminal token mechanism, same generic formatter refusal, NO new refusal rule and NO formatter policy re-evaluation (Invariant 13; the formatter stays STAMP-ONLY). Under default `advisory` the `false` row stays an aggregate advisory and the run completes — avoiding the withdrawn "Zombie pipeline" advisory-yet-unconditionally-blocking contradiction. **Scope note (symmetric with all terminal policies):** the gate is the *output* boundary, exactly as `contamination_triangulation=strict`. A mid-pipeline raw draft (Stage 2–4, before the Stage-4→5 finalizer pass) is not a gated deliverable in any policy mode; the `false` signal is still visible in the always-populated aggregate from the moment detection runs, and the terminal block is what stops it reaching the *formatted* output a human reviews. This is the shipped definition of the gate, not a new hole introduced here.
**Recompute each pass; nothing cached (C-V6(h)).**
...[truncated 25 chars]
The schema contains bidirectional/invisible Unicode control characters in a regex used to validate relative paths. Such characters can enable display-vs-parse mismatches, letting reviewers miss dangerous content or causing downstream tools to interpret text differently than humans expect. In a shared contract/schema file, this is especially risky because many agents and validators may trust and reuse it broadly.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/Imbad0202/academic-research-skills/shared/contracts/evidence/evidence_row_v1_2.schema.json",
"title": "ARS Shared Evidence Row v1.2 — cross-document consistency",
"description": "Closed observation-level evidence-row/1.2 carrier for the cross-document consistency advisory. One row integrity-binds the complete ordered bilateral or preregistration three-witness evidence set. Evidence and checked-scope states are caller-supplied semantic observations whose bytes are replayed; they are not agreement, completeness, readiness, acceptance, or authorization findings.",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"surface",
"row_id",
"pair_kind",
"observation_key",
"deviation_id",
"deviation_
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/Imbad0202/academic-research-skills/shared/contracts/re_review/traceability.schema.json",
"title": "Re-review Phase 2B Traceability Sidecar (machine-readable Schema 11 sidecar)",
"description": "Phase 2B (letter-revealed) final traceability artifact of the Spec B three-gate re-review contract. Every difference between a committed 2A verdict and the final matrix verdict rides a typed AdjustmentRecord (closed basis set, §3.4); the 2A new-issue set is carried FROZEN (whole-record byte-identical, §13 witness); all user-answerable states (§6 G2) resolve through typed records inside the deferral loop, each re-emission incrementing revision and superseding the prior emission by hash. the deterministic checker (not shipped; rules apply) recomputes every invariant and the �
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/Imbad0202/academic-research-skills/shared/contracts/re_review/traceability.schema.json",
"title": "Re-review Phase 2B Traceability Sidecar (machine-readable Schema 11 sidecar)",
"description": "Phase 2B (letter-revealed) final traceability artifact of the Spec B three-gate re-review contract. Every difference between a committed 2A verdict and the final matrix verdict rides a typed AdjustmentRecord (closed basis set, §3.4); the 2A new-issue set is carried FROZEN (whole-record byte-identical, §13 witness); all user-answerable states (§6 G2) resolve through typed records inside the deferral loop, each re-emission incrementing revision and superseding the prior emission by hash. the deterministic checker (not shipped; rules apply) recomputes every invariant and the �
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
> **Canonical wording note:** R-L3-2-A carries the **v3.10 PR-B broad form** (default-advisory + opt-in strict extension across contamination AND temporal namespaces; temporal strict not yet wired). This block is the single source of truth for the wording; the contamination mirrors below are intentionally *by-ID references*, not full-block copies (see the "Mirrored in (contamination rules)" note).
<!-- canonical:R-L3-2-A -->
- **R-L3-2-A (default-advisory + opt-in strict extension):** By default, contamination and temporal-integrity signals never block emission on their own; in a namespace that accepts a `strict` value, a user-enabled strict terminal policy may promote that namespace's specified signals to non-acknowledgeable terminal blockers. v3.10 accepts a strict value for `contamination_triangulation` only; `temporal_integrity` accepts `advisory` only (no temporal strict path exists yet). This follows the v3.5 Collaboration Depth Observer + v3.6.8 LOW-WARN precedent: hard-gating contamination by default would amount to refusing to cite mid-2024+ preprints en masse, which is too coarse — so the terminal promotion is opt-in (off by default), scoped to the namespace's accepted-strict signals, and surfaced via the §formatter terminal gate, never silently.
<!-- /canonical:R-L3-2-A -->
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
- **R-L3-2-B (no retroactive computation):** bibliography_agent computes contamination_signals at ingest time, not at audit time. Re-running the check post-hoc on existing entries is a separate batch operation (deferred to user invocation; not part of the cite-time finalizer).
<!-- /canonical:R-L3-2-B -->
<!-- canonical:R-L3-2-C -->
- **R-L3-2-C (triangulation count over present fields):** k is computed over `*_unmatched` fields that are present. Absent fields are excluded from the count and do not default to either `true` or `false`. k_max reflects how many lookups were successfully run; the (k, k_max) pair together determines the annotation tier.
<!-- /canonical:R-L3-2-C -->
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
---
## Dashboard Output Rules
1. Produce full version when user explicitly requests it
2. **Append simplified version to checkpoint notification after each stage completion**
The README advertises activation through very broad natural-language phrases such as ordinary requests to write or review a paper. In agent platforms that auto-route based on trigger text, this can cause unintended invocation of a powerful orchestration skill, unexpectedly launching multi-stage workflows or influencing handling of unrelated requests.
L020 says the skill 'does not perform substantive work' and only handles orchestration. However, later sections assign the orchestrator itself Stage 6 PROCESS SUMMARY generation (L148, L523-L525) and the collaboration_depth_agent scores the user's collaboration pattern and produces advisory content for checkpoints and the final record (L250, L531-L555), which goes beyond mere dispatch/transition management.
No suspicious patterns detected.