Skip to content

Releases: eyelock/ynf

v0.4.0

Choose a tag to compare

@eyelock eyelock released this 30 Oct 17:03
4b0fa22

ynf v0.4.0

Each run's telemetry budget now reaches ynr, and ynf moves to the current ynh, ynr and ynm releases. Nothing has been removed, and no existing lane changes behaviour.

The spool manifest carries the run's budget: run_quota_bytes

ynf holds each run's spool folder to telemetry.run_quota (64 MiB by default). Until now that budget was never handed to ynr. The manifest ynf writes for each run (manifests/<run id>.json) now carries it as run_quota_bytes, in bytes, beside the run, lane, harness, focus, item, step and uid.

From ynr 0.3.1, ynr serve reads it: it stops reading a run folder that exceeds its budget, and stamps what it shipped from that run with ynr.provenance.warning=over-budget. A ynr that predates the field ignores it, and a manifest without it is read with the 64 MiB default.

Pins

The factory image and CI are tested against:

  • ynh 0.14.0 (was 0.12.0)
  • ynm 0.4.2 (was 0.4.1)
  • ynr 0.3.2 (was 0.2.2)

ghcr.io/eyelock/ynf-factory:0.4.0 carries ynh 0.14.0 and ynm 0.4.2. What the new ynh brings to a factory run includes: sensors from an included harness run against that harness (and an include can opt out with "sensors": false), a harness's includes baked into its image, and the harness's own repository refreshed on every run. ynh 0.14.0 still lists the agent-run-harness-path and agent-run-fetches-includes features, so folder harnesses run as before.

ynf's CI now also runs ynr's conformance rule 13 (never into memory), with ynm on the PATH, and it passes.

Upgrading from 0.3.0

Nothing to change. run_quota_bytes is written for you from telemetry.run_quota. To have ynr enforce it, run ynr 0.3.1 or later.

Install

  • brew install eyelock/tap/ynf
  • ghcr.io/eyelock/ynf-factory:0.4.0

v0.3.0

Choose a tag to compare

@eyelock eyelock released this 19 Oct 23:58
908f3db

ynf v0.3.0

Two new lane settings let you say more about which paths a run may touch, and lanes validate now catches a harness pinned to a branch. Everything is optional and nothing has been removed.

Append-only paths: pr.append_only_paths

A lane can list paths that a run may add to but not change. The diff gate reads how each path changed (added, modified, deleted, type changed; a rename counts as a deletion plus an addition) and allows additions only. A refused run escalates, and the refusal names each path and how it changed:

diff gate refused: <path> (append-only: modified|deleted)

For example: diff gate refused: internal/x/x_test.go (append-only: modified), internal/y/y_test.go (append-only: deleted).

The built-in protected paths and protected_paths are judged first, then allowed_paths. Shadow mode asks the same question, so its gate_accepted agrees with the live gate.

The limit: append-only does not stop a new file from changing how existing tests run. A Go TestMain or init() in a new _test.go, or a new conftest.py, passes the gate. The companion on the harness side is the ynh "test trust" sensors, which check that no tests were lost, that a new test fails before the change, and run mutation testing on the diff.

Review paths: pr.review_paths

Routing only. When a run touches a path matching pr.review_paths, the pull request opens as usual, labelled ynf:review-paths, with a ### Touches review paths section in its body listing the paths. It requests no reviewers and changes no decision. The enforced version is a CODEOWNERS file plus a ruleset that requires code-owner review.

lanes validate refuses a harness pinned to a branch

ynf lanes validate now applies the same check as a run and ynf harness: a harness pinned to a branch is refused, because a branch moves. Use a tag or a commit. To tell a branch from a tag or commit, validate reads the pin repository's refs, so it needs the network for a lane with a pinned harness.

Run record: added and deleted

The run record gains added and deleted lists beside changed. changed is unchanged. A path in changed that is in neither list was modified, and a record without the new lists reads every change as a modification.

Pins

The factory image and CI are tested against:

  • ynh 0.12.0
  • ynm 0.4.1
  • ynr 0.2.2

Upgrading from 0.2.0

Nothing was removed and no existing lane changes behaviour. pr.append_only_paths and pr.review_paths are new, optional lane settings. The one change you may notice is that ynf lanes validate now fails a lane whose pinned harness is a branch (a run already refused it), and it needs the network for pinned lanes.

Install

  • brew install eyelock/tap/ynf
  • ghcr.io/eyelock/ynf-factory:0.3.0

v0.2.0

Choose a tag to compare

@eyelock eyelock released this 08 Oct 10:11
2774840

ynf v0.2.0

Shadow mode

  • ynf shadow run --auto-approve lets a shadow run grant edits on the host.
  • Shadow mode measures a lane's yield against closed tickets: it replays the lane on the commit before a human fix, grades the attempt, and changes nothing outward.

Runner detection, and finding tools only on PATH

  • A lane with no runner uses ynh when it is detected, and otherwise runs its command.
  • ynf finds ynh and ynr only on PATH, like any other command.

Sensor scope

  • sensor_scope may only narrow a declared sensor. It can no longer replace one, but it may keep the declared environment prefix verbatim.

Memory

  • Memory writes queue while ynm is down and are sent when it is back.
  • Failure memories carry what the run reported, so memory can explain a failure. Failure records end with a full stop.
  • ynm's store is found as ynm finds it: the git root, then YNM_HOME or ~/.ynm, with no walk up.

OpenTelemetry on ynr's contract

  • Steps are traced as ynf.step spans on ynr's OpenTelemetry contract.
  • Intake events are mirrored as CloudEvents.
  • Each run gets its own spool folder, which can be its own volume, and a run's manifest names its user.
  • ynr serve collects a factory job.
  • Quotas apply to what a run spools.
  • A job cleans up run volumes left behind by a ynf that was killed.
  • ynr conformance and the full-chain trace check run in CI.

Harnesses

  • A lane whose harness is a folder runs on the process and inline executors, as well as the others.
  • A harness pin's host/path form is normalised to https.
  • On the host, a harness pinned from git runs without a copy, and an unreadable harness folder is an error.
  • A folder harness goes straight to ynh when ynh reports agent-run-harness-path, and it supports git includes.

PR checks

  • ynf reads every required check, including those set by rulesets, by App, and across pages.
  • A PR whose required checks are never reported stays proposed.
  • No-CI escalation: a PR with no CI is warned about, and can be escalated after a delay.

Item references and reasons

  • Short references find adopted PRs, and items show the latest reason.
  • --version is supported.
  • A sweep that finds nothing now says so, with a hint.
  • Calibration runs after e2e, and skips a fixture with no fixed state, saying why.

The public repository

  • ynf is now public. The private plumbing is gone, Terraform keeps the repository public, and security and conduct concerns go to support@eyelock.net.

Pinned: ynh 0.12.0, ynm 0.4.1, ynr 0.2.2.

Upgrading from 0.1.0

  • YNF_YNH_BIN and YNF_YNR_BIN are removed. Put ynh and ynr on PATH.
  • Lanes have an id field.
  • There is a new telemetry config.
  • calibrate.skip is new.
  • no_ci_after and when.no_ci are new.
  • ynm is detected only when a store is configured.
  • ynf shadow run --auto-approve is new, for granting edits to a shadow run on the host.
  • Replaying retry decisions recorded before 0.2.0 shows a wording difference in the reason.

Install

brew install eyelock/tap/ynf, or ghcr.io/eyelock/ynf-factory:0.2.0.

v0.1.0

Choose a tag to compare

@eyelock eyelock released this 05 Oct 05:20
3aac2c8

ynf 0.1.0

The first release of ynf, your named factory: the outer loop around agent runs. ynf watches tickets and pull requests, decides what to do with each one, runs an agent (through ynh) or a command in containment on a fresh checkout, proposes the change as a draft pull request, and follows it through CI and review. A human always merges. What keeps going wrong is remembered in ynm.

Docs: https://eyelock.github.io/ynf/, with two tutorial tracks: ynf on its own, and the factory with ynh, ynm and ynf together.

What's in it

The loop

  • Work items with a durable state machine, and a pure decider: every decision is recorded and ynf replay recomputes it, under the recorded lanes or a changed lanes file.
  • Lanes in versioned YAML with CEL guards. A configuration repository's lanes lie under each repository's own, merged key by key. ynf lanes validate --repo checks a repository's lanes merged as ynf would.
  • One claim at a time: leases with heartbeats and fencing, over SQLite or S3. A crashed run is restarted, not resumed.
  • Stop conditions: yield floors, pausing a lane with a reason, and ynf stats per lane.

Starting work

  • From a search (sweep, serve), a GitHub webhook (serve --listen), a CI event (handle, with --lane), or by instruction: ynf start <ticket> or ynf start --prompt … --label ….
  • Trackers besides GitHub, through their MCP server, such as JIRA. ynf calls the tools itself, with no model.
  • GitHub.com and GitHub Enterprise Server as forges, with host-qualified item keys.

Running it

  • Runners: ynh, for an agent with its harness, sensors and budgets, or any command.
  • A lane may pin the agent's model (run.ynh.model) and effort (run.ynh.effort), tighten its budgets and scope its sensors. It never loosens or redefines them.
  • Executors: docker, with an egress proxy and an allow list; process, attended only; and inline, inside the factory image under the job runner's containment.
  • Each run gets a self-contained checkout, so git works inside the container.
  • --auto-approve only inside containment.

Seeing what happened

  • Every run records the model, effort, turns, tokens (input, output and cache reads), cost, the cap that bound it, and the harness version.
  • ynf stats breaks every lane down by model and effort.
  • Failure signatures name what failed: the sensor, the budget cap, the CI check that diverged from the loop's sensors. Each occurrence is written to ynm, tagged occurrence, locally or over HTTP to a hosted ynm with a machine token.
  • ynf doctor, forges, trackers, ticket and harness check a factory before it's relied on.

The factory image
ghcr.io/eyelock/ynf-factory:0.1.0, for amd64 and arm64: ynh 0.10.0's image with ynf and ynm 0.3.0. Build your harness on it with ynh image … --base, and run it as a job (Run the factory image).

Install

brew install eyelock/tap/ynf

ynf pairs with ynh 0.10.0 and ynm 0.3.0. Both are optional: ynf detects them, and runs commands without them.