File size: 3,420 Bytes
21a9138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Behaviour extractor (layer 1)

This is the static extractor that wrote the `Behaviour summary (automated, not a verdict):` section of every training and
evaluation state for d3-mini-agentcode. It reduces a diff or a code snippet to *what it does*: behaviours such as
network egress, process spawn, environment or credential reads, file writes, persistence, install hooks and
obfuscation markers. Each behaviour comes with a `file:line`, a concrete operand and a short piece of evidence.

It never executes the analysed code. It describes and doesn't judge: many ordinary changes should show behaviours
(build hooks, test subprocesses, HTTP clients). The model weighs them against the task and the repository baseline.

## Install
```
pip install -r requirements.txt     # tree-sitter 0.26.0 + tree-sitter-language-pack 1.12.5 (the versions we used)
```
Without tree-sitter the extractor falls back to line regexes with reduced coverage, and says so in the report's
`notes`. Tested with Python 3.13.

## Build a model input (run from this directory)
```
python make_state.py diff change.diff --task-file task.txt
python make_state.py snippet run.py --lang py --task "Clean up the build cache"
```
This prints the four-section state the model was trained on (task, repository baseline, behaviour summary, change),
with the same 8,192-token budget. Pass it as `state=` to `model.system_one(...)`.

In Python:
```python
import make_state as ms
rep = ms.analyse_diff(diff_text, task=task)            # or ms.analyse_snippet(code, lang="py", task=task)
state = ms.state(task, ms.baseline_text(None), ms.summary(rep), diff_text)
```

**Repository baseline.** In training and evaluation, the baseline listed the most common behaviour operands across the
repository's (or source's) other ordinary changes. To build one, run the extractor on a sample of the repo's ordinary
changes, then accumulate them with `ms.add_to_baseline(acc, rep)` into `acc = ms.new_baseline()`, and pass
`ms.baseline_text(acc)`. With no history, it's `(no repository history available)`.

## The extractor on its own
```
python -m behaviour diff FILE|-    [--task T | --task-file F] [--format text|json|both]
python -m behaviour snippet FILE|- [--lang js|ts|py|sh] [--task T]
python -m behaviour package DIR    # whole-directory mode (packages are out of scope for the model)
python -m behaviour kinds          # the behaviour list
python -m unittest behaviour.tests # tests
```
Python API: `from behaviour import analyse_diff, analyse_snippet, analyse_package` returns a dict with `behaviours`,
`counts`, `stats` and `text` (the compact summary, at most 60 lines).

## Coverage
- **Best:** Python, JavaScript/TypeScript (tree-sitter, with simple source-to-sink tracking) and shell (a quote-aware
  tokenizer, also used for CI `run:` blocks, npm scripts, Dockerfile RUN and Makefile recipes).
- **Config files:** package.json, .npmrc, pip.conf, .env, requirements, pyproject/setup.cfg, CI YAML, pre-commit,
  Dockerfile, Makefile, .pth, and binary or archive detection by magic bytes.
- **Weaker:** other languages get line-level patterns only. The model's results in other languages were measured with
  these summaries, as they are.

## Check
We rebuilt the states of all 2,150 real-code rows of the 14-language evaluation set with this copy. Every state was
byte-identical to the one the model was scored on.

Licence: Apache-2.0 (see ../LICENSE).