autoresearch — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited autoresearch (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
An autonomous experimentation loop for any programming task. You define the goal and how to measure it; the agent iterates autonomously -- modifying code, running experiments, measuring results, and keeping or discarding changes -- until interrupted.
Inspired by Karpathy's autoresearch, enhanced with battle-tested patterns from pi-autoresearch.
autoresearch.jsonl (machine) + results.tsv (human).autoresearch.checks.sh exists) before measuring.Before any experimentation begins, work with the user to establish these parameters. Ask the user directly for each item. Do not assume or skip any.
Ask the user:
What are you trying to improve or optimize?
>
Examples: execution time, memory usage, binary size, test pass rate, code coverage, API response latency, throughput, error rate, benchmark score, build time, bundle size, LLM output quality, prompt effectiveness, skill accuracy, etc.
Record the user's answer as the goal.
Ask the user:
How do we measure success? What exact command produces the metric?
>
I need: 1. The command to run (e.g.,./evaluate.sh,npm run benchmark,pytest --tb=short) 2. Metric output format: The command must printMETRIC name=valuelines to stdout. Example output:METRIC quality_score=8.333. Primary metric name: Which METRIC name is the main optimization target? 4. Direction: Is lower better or higher better?
>
If your command doesn't emit METRIC lines yet, I can help you wrap it.
Record:
METRIC_COMMAND: the command to runPRIMARY_METRIC: the name of the primary metric (e.g., quality_score)METRIC_DIRECTION: lower_is_better or higher_is_betterAsk the user:
Which files or directories am I allowed to modify?
>
And which files are OFF LIMITS (read-only)?
Record:
IN_SCOPE_FILES: files/dirs the agent may editOUT_OF_SCOPE_FILES: files/dirs that must not be modifiedAsk the user:
Are there any constraints I should respect?
>
Examples: - Time budget per experiment (e.g., "each run should take < 2 minutes") - No new dependencies - Must keep all existing tests passing - Must not change the public API - Must maintain backward compatibility - VRAM/memory limit - Code complexity limits (prefer simpler solutions)
Record as CONSTRAINTS.
Ask the user:
How many experiments should I run, or should I just keep going until you stop me?
>
You can say a number (e.g., "try 20 experiments") or "unlimited" (I'll run until you interrupt).
Record as MAX_EXPERIMENTS (number or unlimited).
Inform the user of the default simplicity policy:
Simplicity policy (default): All else being equal, simpler is better. A small improvement that adds ugly complexity is not worth it. Removing code while maintaining or improving the metric is a great outcome. I'll weigh the complexity cost against the improvement magnitude. Does this policy work for you, or do you want to adjust it?
Record any adjustments as SIMPLICITY_POLICY.
Ask the user:
Is there a correctness check that must pass before I measure the metric?
>
For example: lint checks, type checks, test suites, syntax validation. If yes, I'll create an autoresearch.checks.sh script that must exit 0 before any metric measurement. Failed checks = experiment treated as crash.If yes, create autoresearch.checks.sh with the specified checks.
Summarize all parameters back to the user in a clear table:
| Parameter | Value |
|---|---|
| Goal | ... |
| Metric command | ... |
| Primary metric | ... |
| Direction | lower is better / higher ... |
| In-scope files | ... |
| Out-of-scope files | ... |
| Constraints | ... |
| Max experiments | ... |
| Simplicity policy | ... |
| Checks script | yes / no |
Ask the user to confirm. Do not proceed until confirmed.
Once confirmed, write the session contract file autoresearch.md in the workspace:
# Autoresearch Session
- **Goal**: <goal>
- **Primary metric**: <PRIMARY_METRIC> (<METRIC_DIRECTION>)
- **Metric command**: `<METRIC_COMMAND>`
- **Checks command**: `./autoresearch.checks.sh` (or "none")
- **Budget**: <MAX_EXPERIMENTS> experiments
- **Branch**: autoresearch/<tag>
- **In-scope**: <IN_SCOPE_FILES>
- **Out-of-scope**: <OUT_OF_SCOPE_FILES>
- **Constraints**: <CONSTRAINTS>
- **Simplicity**: <SIMPLICITY_POLICY>
- **Started**: <ISO timestamp>Once the user confirms:
autoresearch/may30).Create the branch: git checkout -b autoresearch/<tag>.
results.tsv with the header: experiment\tcommit\tmetric\tstatus\tdescriptionautoresearch.jsonl (empty, will be appended to)Add results.tsv, run.log, autoresearch.jsonl, and autoresearch.md to .git/info/exclude so they stay untracked.
Record the result as experiment 0 with status baseline. Log the baseline to both results.tsv and autoresearch.jsonl.
Baseline established: [PRIMARY_METRIC] = [value] Starting autonomous experimentation loop.
Run this loop continuously. Do not stop to ask the user. Run until:
MAX_EXPERIMENTS is reached, ORLOOP:
1. THINK - Analyze previous results, ASI from past experiments, and current code.
Generate a hypothesis: "I believe <change> will improve <metric> because <reason>."
Check autoresearch.ideas.md for queued hypotheses.
Consider: what worked, what didn't, what hasn't been tried.
2. EDIT - Modify the in-scope file(s) to implement the hypothesis.
Keep changes focused and minimal per experiment.
3. COMMIT - Stage and commit before running:
`git add <in-scope-files> && git commit -m "experiment N: <description>"`
This ensures every experiment has a clean revert point.
4. RUN - If autoresearch.checks.sh exists, run it first.
If checks FAIL: log status = "checks_failed", revert commit
(`git reset --hard HEAD~1 && git clean -fd -e 'autoresearch.*' -e 'results.tsv' -e 'run.log'`),
skip to LOG.
If checks PASS (or no checks): execute the metric command.
Redirect output to run.log: `<command> > run.log 2>&1`
5. MEASURE - Parse METRIC lines from run.log.
Extract PRIMARY_METRIC value. Record all secondary metrics.
If extraction fails (crash/error), read the last 50 lines
of run.log for diagnostics.
6. DECIDE - Compare PRIMARY_METRIC to the current best:
- KEEP: Metric improved AND improvement exceeds noise threshold.
Noise threshold = max(0.01, 1.0 × MAD of recent kept scores).
Use the last 5 kept experiments for MAD; if < 3 kept, use 0.01.
Improvements within noise are treated as DISCARD.
Update the "best" baseline. Log status = "keep".
- DISCARD: Metric same, worse, or improved within noise. Revert:
`git reset --hard HEAD~1 && git clean -fd -e 'autoresearch.*' -e 'results.tsv' -e 'run.log'`
Log status = "discard".
- CRASH: Metric extraction failed or runtime error.
Attempt a quick fix (typo, import, simple error).
If fixed, amend the commit (`git commit --amend`) and rerun from step 4.
If unfixable after 2 attempts, revert (same as DISCARD)
and log status = "crash".
7. LOG - Append to results.tsv:
experiment_number commit_hash metric_value status description
Append to autoresearch.jsonl (one JSON object per line):
{
"experiment": N,
"status": "keep|discard|crash|checks_failed|baseline",
"hypothesis": "<what we thought would improve>",
"primary_metric": <value>,
"secondary_metrics": { "<name>": <value>, ... },
"commit": "<hash or null>",
"description": "<what changed>",
"learned": "<insight that survives revert>",
"rollback_reason": "<why discarded, if discarded>",
"next_action_hint": "<what to try next>",
"confidence": <MAD ratio or null>,
"timestamp": "<ISO timestamp>"
}
If a hypothesis was deferred, append it to autoresearch.ideas.md.
8. CONTINUE - Check plateau. Go to step 1.The metric command MUST print lines in this format to stdout:
METRIC <name>=<value>Rules:
[\w.]+ (alphanumeric, underscores, dots)Examples:
METRIC quality_score=8.33
METRIC structure=9.0
METRIC coverage=7.5
METRIC latency_ms=142Every experiment log entry in autoresearch.jsonl MUST include these fields:
ASI is the ONLY structured memory that survives a git revert. It prevents the agent from repeating failed approaches and builds cumulative knowledge across the session.
When generating experiment ideas, follow this priority order:
learned and next_action_hint from past experiments.autoresearch.ideas.md for queued hypotheses.Track a sliding window of the last PLATEAU_WINDOW experiments (default: 5). If ALL experiments in the window were discarded (no improvement), check whether the plateau is within measurement noise using confidence scoring (see below).
Report:
Plateau detected after [N] consecutive failed experiments. Best score: [value]. Confidence: [ratio]x MAD. Consider: 1. Trying a fundamentally different approach 2. Reviewing the ideas backlog for untried directions 3. Stopping if confidence is high (improvements may be at measurement ceiling)
Continue if budget remains, but shift strategy to radical changes.
For noisy metrics (benchmarks with variance between runs), track confidence using Median Absolute Deviation:
Interpretation:
The logged confidence ratio is advisory -- it provides interpretive context but does not override the binding noise threshold in DECIDE (which uses the same MAD stats). The DECIDE gate is the binding rule; confidence is for human/agent reasoning about result reliability.
For metrics with zero variance (deterministic), confidence is null and the noise threshold falls back to the 0.01 absolute minimum.
autoresearch.checks.sh.If the session was interrupted (context limit, user stop, crash):
autoresearch.md to re-establish goal, metric, scope, and constraintsautoresearch.jsonl to reconstruct current state:learned, next_action_hint) from the last few experimentsgit log --oneline on the autoresearch branch to see kept experimentsautoresearch.ideas.md for queued hypothesesEach experiment consumes context. To avoid degradation:
rather than waiting for quality to degrade from context saturation
autoresearch.md (config),the last 5 entries from autoresearch.jsonl (recent ASI), autoresearch.ideas.md, and results.tsv summary. Do NOT reload all research, gold standards, or full experiment history into context
The JSONL learned and next_action_hint fields carry the signal without the bulk
When the loop ends (budget reached, user interrupts, or plateau):
learned fields)git log --oneline <start_commit>..HEAD
autoresearch.ideas.md.METRIC <name>=<value> # one per line, at line start
METRIC quality_score=8.33
METRIC structure=9.0Names: [\w.]+, values: finite numbers. Primary metric named in session config.
Tab-separated, 5 columns:
experiment commit metric status description
0 a1b2c3d 0.997900 baseline unmodified code
1 b2c3d4e 0.993200 keep increase learning rate to 0.04
2 - 1.005000 discard switch to GeLU activation
3 - 0.000000 crash double model width (OOM)One JSON object per line. Status values: baseline, keep, discard, crash, checks_failed. Each entry contains: experiment, status, hypothesis, primary_metric, secondary_metrics, commit, description, learned, rollback_reason, next_action_hint, confidence, timestamp.
| File | Purpose | Tracked in git? |
|---|---|---|
autoresearch.md | Session contract (goal, config) | No (.git/info/exclude) |
autoresearch.jsonl | Machine log with ASI | No (.git/info/exclude) |
results.tsv | Human-readable results journal | No (.git/info/exclude) |
autoresearch.checks.sh | Correctness gate (optional) | Yes (committed) |
autoresearch.ideas.md | Deferred hypothesis backlog | No (.git/info/exclude) |
run.log | Last command output | No (.git/info/exclude) |
autoresearch/<tag> branchgit add <in-scope-files> && git commit -m "experiment N: <description>"Only stage in-scope files. Never git add -A (risks staging out-of-scope changes).
git reset --hard HEAD~1 && git clean -fd -e 'autoresearch.*' -e 'results.tsv' -e 'run.log'.git/info/exclude)METRIC name=value format.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.