agentleFS
imMamdouhaboammarimMamdouhaboammar/get-fable/skills/fable-tend/CLAUDE.md

get-fable / fable-tend

CLAUDE.md6 starsChanged 3 months agoMITView on GitHub

Tend is an autonomous CI maintainer for GitHub repos: it reviews PRs, triages issues, and fixes CI, powered by Claude or Codex. This repo ships the generator (uvx tend@latest) that stamps each consumer's workflow files, plus the plugins and composite actions those workflows run. No backward compatibility. When a config format or API changes, cut over completely — old formats should fail with a clear error, not silently parse. Simplicity outranks efficiency. Complexity earns its place by preventing wrong outward…

The file

We split this CLAUDE.md into the rules it gives an agent

10 rules. About 0 are common, 7 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    No backward compatibility.

    line 8
  2. Distinctive:

    When overrides are present, the generator renders the base template, parses it, merges the overrides, and re-serializes.

    line 228
  3. Very specific:

    Every consumer runs the environment gate: both secrets live in the tend environment with no repo-level copies.

    line 270
  4. Very specific:

    Before writing guidance outside plugins/, check whether it ends up in a consumer's repo or session.

    line 348
  5. Distinctive:

    When reviewing or surveying a guidance file, ask both questions of it — does this ship, and who acts on it — and ask them of the sections a …

    line 413
  6. Very specific:

    When adding to or editing files in plugins/tend-ci-runner/skills/ or .claude/skills/:

    line 420
  7. Distinctive:

    No specific past-run references: Don't link GitHub Actions runs, cite session IDs, or quote durations from individual incidents.

    line 432
  8. Distinctive:

    No specific past-case references: Don't cite individual past PRs, issues, or commits as supporting precedent for a rule (e.g.

    line 436
  9. Distinctive:

    Keep the actions' Bash as linear installation and plumbing, not a second implementation layer.

    line 473
  10. Distinctive:

    Don't build deterministic YAML steps for work that happens *inside* an agent run.

    line 478

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

Development

Tend is an autonomous CI maintainer for GitHub repos: it reviews PRs, triages issues, and fixes CI, powered by Claude or Codex. This repo ships the generator (uvx tend@latest) that stamps each consumer's workflow files, plus the plugins and composite actions those workflows run.

No backward compatibility. When a config format or API changes, cut over completely — old formats should fail with a clear error, not silently parse.

Simplicity outranks efficiency. Complexity earns its place by preventing wrong outward actions — what the bot posts, approves, merges, or closes — rather than by saving compute. Prefer deleting a mechanism over refining it. "What waste is worth fixing" below says which waste earns a change.

Commands

wt test                                # everything: uv run pytest, then worker/'s vitest
uv run pytest                          # the Python half alone, from the repo root
uvx tend@latest init                   # regenerate workflows from .config/tend.yaml
uvx tend@latest init --dry-run         # preview without writing
uvx tend@latest check                  # verify branch protection, secrets, bot access
uv tool run pre-commit run --all-files # lint: every hook in .pre-commit-config.yaml

The repo root is a uv workspace, and pytest run from it collects every Python test — generator/, proxy/, shared/steps/, and the install-tend scripts — so one pytest is the whole Python run. wt test (defined in .config/wt.toml) adds worker/'s vitest suite and typecheck. Its arguments narrow pytest and nothing else, so a filtered run still pays for worker/; uv run pytest -k render is the Python half on its own.

pre-commit is not on the CI sandbox's PATH, which is why the lint command above carries the uv tool run prefix; a narrower substitute (ruff alone, shellcheck alone) skips ten of the thirteen hooks, including the three repo: local guards — the bang-backtick check, the install-tend mirror sync, and the sandbox_env reserved-set parity check.

Inside a tend session the sandbox has no DNS, so the two tests in generator/tests/test_refresh_consumers.py fail: they drive the script through uv run --script, which resolves its dependencies from PyPI. Nothing else in the suite reaches the network, so a third failure is a real one.

Architecture

Four pieces:

  1. Plugins — install-tend (user-facing setup) and tend-ci-runner (CI skills). Both ship from the same marketplace.
  2. Composite actions — the stable interface, pinned to an immutable release tag (max-sixty/tend/<action-path>@X.Y.Z, the generator's own version — no floating v1). Every action lives under a harness-named path; there is no bare-root default. The two harness runners are:

    • max-sixty/tend/claude@X.Y.Z (Claude) — runs the official claude binary headless (claude -p) inside the shared Anthropic Sandbox Runtime boundary; completion is the process exit code plus result event. Inputs in claude/action.yaml.
    • max-sixty/tend/codex@X.Y.Z (Codex) — installs @openai/codex and shells out to codex exec. Skills are staged on disk and an AGENTS.md in $CODEX_HOME teaches Codex to resolve /tend-ci-runner:NAME slash commands. Inputs in codex/action.yaml. Shares the cross-harness workspace, SRT lifecycle, preflight, and teardown scripts under shared/steps/.

    Both harness runners resolve the bot's numeric ID at runtime, run security and rate-limit preflight, prepare an independent event checkout, run sandbox_setup: and the complete agent turn in one SRT process tree, reap it, and upload bounded session logs. The generated workflow's checkout stays runner-owned on reviewed code for setup and local-action POST chains.

    max-sixty/tend/codex/refresh@X.Y.Z is the Codex support action. A generated serialized workflow runs it weekly to rotate Plus/Pro credentials and publish the full and access-only bundles. It holds no bot token and does not inspect consumer code. Inputs in codex/refresh/action.yaml.

    Removed: claude-interactive, a PTY-supervised variant of the same binary that existed only to dodge the 2026-06-15 Agent SDK metering (which covered claude -p but not interactive sessions). Anthropic paused that change and the default harness now runs the binary rather than the SDK, so nothing selected it. Restore from 036f9c4 if the metering resumes.

  3. Generator (uvx tend@latest init) — stamps workflow files into the consumer's .github/workflows/ from .config/tend.yaml. Picks the right action ref and secret names per harness. Generation is idempotent — running init again overwrites all files from the current config. When the review workflow is generated, it also merges the concurrency.queue ignore into the consumer-owned .github/actionlint.yaml (see "Concurrency and filtering").
  4. Config (.config/tend.yaml) — inputs to the generator. Overrides from defaults only. harness: claude | codex selects the harness (default claude). A per-workflow harness: override (and matching model:) lets a consumer trial a different harness on one workflow at a time. All workflows are generated by default. enabled: false omits a workflow on regeneration. Pausing all of tend is not config: every job that runs the agent checks the TEND_ENABLED repository variable in its if:.

Generated workflows are standalone — full steps: jobs, not workflow_call. The generator owns the entire file. Trusted runner setup (system tools and Actions caches) is defined in setup:; dependency setup against the event tree is defined in sandbox_setup: and runs inside SRT.

Structure

tend/
├── .claude-plugin/
│   └── marketplace.json  # Claude Code marketplace — lists both plugins
├── .agents/plugins/
│   └── marketplace.json  # Codex marketplace — lists both Tend plugins
├── plugins/
│   ├── install-tend/     # User-facing plugin (setup skill)
│   └── tend-ci-runner/   # CI plugin (review, triage, ci-fix, etc.)
│       ├── .codex-plugin/  # Codex plugin manifest
│       └── scripts/      # Helper scripts (survey, run listing)
├── claude/
│   └── action.yaml       # Claude harness composite action (default, headless)
├── codex/
│   ├── action.yaml       # Codex harness composite action
│   ├── refresh/
│   │   └── action.yaml   # Serialized Plus/Pro credential refresh action
│   ├── runner.py         # Codex harness commands (plugin, prompt, execution)
│   └── agents-tail.md    # AGENTS.md appendix for Codex
├── shared/
│   ├── steps/            # Shared composite-action step bodies (Python; bash for the install/plumbing ones)
│   └── system-prompt.md  # Harness-neutral system prompt base
├── proxy/                # Credential-injection proxy (setup_sandbox.py, addon)
├── generator/            # Python package (uvx tend@latest), uv_build backend
│   ├── src/tend/
│   │   ├── config.py     # Reads .config/tend.yaml
│   │   ├── workflows.py  # Generates workflow YAML
│   │   ├── checks.py     # Security checks (branch protection, secrets)
│   │   └── cli.py        # Click CLI (init, check)
│   └── tests/
├── site/                 # Astro marketing site (tend-src.com)
├── worker/               # Cloudflare Worker — serves the 2 site data streams
├── data/                 # consumers.json — Worker's input (refreshed weekly)
├── docs/
│   └── security-model.md
└── pyproject.toml        # uv workspace root: dev deps + the lockfile

Key details

The tend-*.yaml files in .github/workflows/ are generated by uvx tend@latest init from .config/tend.yaml. Edit the generator or config, not the workflow files directly.

The generator is a Python package under generator/ — uses the uv_build backend, requires Python 3.11+. Runtime dependencies: click, jinja2, ruamel.yaml. It is the one member of the repo's uv workspace, so the lockfile and the dev dependencies (pytest, pytest-regtest, and the pinned mitmproxy the proxy addon imports) live in the root pyproject.toml, and the dev environment needs 3.12+ even though the package supports 3.11.

Consumer repos regenerate their tend-*.yaml workflows nightly (tend itself included — it dogfoods its own workflows). Changes to the generator do not require manual regeneration in downstream repos.

Tend's own tend-*.yaml workflows track the latest published release. They update each night via uvx tend@latest init. Updating earlier to the latest release (e.g., during a release commit) is fine. Never regenerate them with the in-tree generator: the action ref is pinned to the generator's own version (max-sixty/tend/<harness>@X.Y.Z), so an unreleased in-tree version stamps a tag that does not exist yet, and the workflow's uses: fails to resolve. Between a generator commit and the next release the committed workflows lag the in-tree generator; that is expected, and the gap closes at the next release (which tags X.Y.Z before regenerating, so the pin always resolves).

claude_version in claude/action.yaml is an exact version taken from npm's latest dist-tag, not stable. stable lags several releases, and pinning it wouldn't keep un-promoted code out of the job anyway: install.sh always downloads the latest build as its bootstrap installer, and only the agent session runs the pin.

Generator vs consumer ownership

AspectOwnerLives in
Trigger events (on:)Generatorgenerated workflow
Filter conditions (if:)Generatorgenerated workflow
Engagement verification (mention)Generatorgenerated workflow
Concurrency groupsGeneratorgenerated workflow
PermissionsGeneratorgenerated workflow
CheckoutGeneratorgenerated workflow
Composite action callGeneratorgenerated workflow
Runner setup (system tools, Actions cache)Consumersetup: in .config/tend.yaml
Event-tree setup (dependencies, generated files)Consumersandbox_setup: in .config/tend.yaml
Bot identity, auth configConsumer.config/tend.yaml
Skills (generic)Tendtend-ci-runner plugin (marketplace)
Skills (project-specific)Consumer.claude/skills/ in their repo

Workflow overrides

Consumers extend generated workflows via YAML keys that the generator merges into the rendered YAML using RFC 7396 (JSON Merge Patch — mappings deep-merge, scalars and lists replace, null deletes):

workflows:
  review:
    workflow_extra:
      env:
        MY_VAR: hello
    jobs:
      review:
        timeout-minutes: 240
        runs-on: ubuntu-22.04-large

YAML has a native null literal, so RFC 7396's null-deletes works directly — e.g. drop the cron from a scheduled workflow while keeping workflow_dispatch:

workflows:
  nightly:
    workflow_extra:
      on:
        schedule: null

Workflow-level (workflow_extra) and job-level (jobs.<name>) overrides are supported; step-level is not — setup: handles trusted runner steps and sandbox_setup: handles event-workspace commands. No allowlist of override keys; unknown job names produce a warning.

When overrides are present, the generator renders the base template, parses it, merges the overrides, and re-serializes. Output YAML formatting differs slightly from the base template (block-style lists) but is functionally identical.

Auth

Each consumer creates a GitHub bot account and a classic PAT with repo, workflow, notifications, write:discussion, gist, and user. repo is required on public and private repositories alike — install-tend mints exactly that set, and the nightly scope audit (pat_scope_audit.py) reports anything narrower as missing. The PAT and a Claude OAuth token are stored as secrets in the repo's tend GitHub Environment, whose deployment branch policy admits only the branches tend check confirmed the bot cannot write — the default branch and any protected_branches that exist and are protected. A workflow the bot pushes to any other ref is refused them before its first step. Two things use the gist scope, both through bot-owned secret gists: review-reviewers keeps a per-month structured evidence store (avoids the 65 KB comment-body limit), and the experimental memory_gist setting persists Claude Code's auto memory across runs. The user scope lets install-tend set the bot's profile bio (PATCH /user) so the account's authorization stance is discoverable on the bot's user page.

The agent may use PAT-backed GitHub API and git access for any repository the bot account can reach; this cross-repository access is intentional. Credential isolation keeps the PAT itself out of the agent process. If the PAT is stolen by compromising the runner or proxy, its repo scope grants full write to every repository the bot account can reach, private ones included. Fine-grained PATs allow per-category scoping but don't support outside collaborators (GitHub roadmap #601, not shipped).

Current privilege model: write + branch protection + environment gate. The bot has write access; a merge restriction (ruleset or branch protection) is the primary security boundary — without it the bot can merge its own PRs — and the tend environment keeps the operational secrets out of any run the bot can cause on its own. tend check verifies both are configured correctly, and --fix creates either. See docs/security-model.md for the full threat model. Alternative models (GitHub App, triage+fork) are in TODO.md.

Every consumer runs the environment gate: both secrets live in the tend environment with no repo-level copies. This repo's own workflows name it too, including the hand-maintained ones the generator never touches.

Concurrency and filtering

Events pass through three layers before the bot does work:

  1. GHA if: conditions — evaluated by Actions before the job starts. A false condition skips the job entirely (never enters the concurrency group, never queues).
  2. Custom should_run pre-checks — cheap deterministic steps that decide whether the agent boots: mention's verify job checks engagement, and notifications' check repairs repository watching, captures a paginated cutoff snapshot, and finds configured-bot PR conflicts whose current heads have not already been deferred for manual resolution.
  3. Concurrency groups — at most one running job per group.

Concurrency groups:

WorkflowGroup keyCancel-in-progress
reviewworkflow-PR#no — killing a session discards a review it can still deliver; queue: max holds pending PR events within GitHub's queue limit while it folds the push in and posts
mention-relaynonestateless — secretless job that re-posts review events to mention as a repository_dispatch
mention/verifynonestateless
mention/handleworkflow-handle-issue#|PR#no — each mention runs to completion
triageworkflow-issue#yes — latest comment wins
notificationstend-notificationsno — one poll drains notifications and repairs bot PRs at a time
ci-fixworkflow-<watched workflow>-<branch>no — a session mid-fix may already have pushed a branch or opened a PR
nightly / weeklynonecron-serialized
codex-auth-refresh (codex only)tend-codex-auth-refreshno — only this workflow may rotate the refresh-token chain, so a second refresher must never race it

Fork guard. Workflows whose triggers can fire from a fork's own Actions (schedule, workflow_dispatch, workflow_run, issues) carry if: github.repository_owner == '<owner>' so a fork that's enabled Actions but doesn't have the bot/Claude secrets no-ops cleanly. The canonical owner is detected at init time (via gh repo view, walking source.owner.login if the local repo is itself a fork) and pinned in the generated workflow. tend-review uses pull_request_target (base repo only) and tend-mention-relay, which carries tend-mention's review events, already filters forks via head.repo.full_name == github.repository, so neither needs the guard.

Red branches. A red default branch fails every push that follows it, each on its own commit, so ci-fix keys its group on the branch — a commit-keyed group collapses nothing, since the burst is distinct commits rather than one commit retried. The watched workflow is in the key too, so a red publish-site isn't starved behind a stream of red ci. ci-fix's group is job-level, not workflow-level: most workflow_run events are green runs the job's if skips, and a skipped job never enters the group.

GHA queue depth. Review sets queue: max, so pending PR events within GitHub's queue limit wait and a later push cannot replace ready_for_review. GitHub accepts the key; actionlint's schema does not, so init merges the matching ignore into .github/actionlint.yaml, which the binary reads for every invocation. Mention/handle and notifications keep the default one-pending-run queue; when a third job arrives while one runs and one queues, the pending job is replaced. For mention, mitigation lives in the skill prompts: dedup if the bot already responded to the triggering comment; self-heal earlier comments without a bot reply (oldest first). The workflow injects the queue-to-run time delta (seconds between event timestamp and job start) into the prompt — over ~40 s indicates the job was queued behind another run, making conversation drift more likely. Notifications stay unread until a poll records an outcome, so the newest pending run covers a replaced poll. ci-fix keeps the default too, and wants it: while a session works a red branch, the newest unsuccessful run carries that branch's current state, so replacing the pending run loses nothing.

Shipped guidance and tend's own

Two kinds of guidance live in this repo, split by which repo the text governs.

Shipped guidance is any text that reaches a repo other than this one. It tells the bot what to do in a repo it maintains, and has to hold in repos nobody here has seen. More of it than plugins/**: shared/system-prompt.md and the two directives compose_system_prompt.py prepends, codex/agents-tail.md, the header comment workflows.py stamps into every generated workflow, and docs/tend.example.yaml, which a pre-commit hook mirrors into install-tend. Before writing guidance outside plugins/, check whether it ends up in a consumer's repo or session.

Tend's own guidance is read only here: CLAUDE.md, TODO.md, docs/security-model.md, and .claude/skills/. It tells a session — the bot's or yours — how to work on tend.

The test for a line of shipped text: does it hold in a repo whose maintainer disagrees with us? What tend values, what this repo will spend complexity on, how many open PRs is too many, how much runner time is worth saving — those are one maintainer's calls. Shipped, they make every consumer's repo answer to tend's; they belong here instead. Mechanics ship freely: how GitHub behaves, what the harness does, what a session must never do. A default a consumer might want differently ships as a default their overlay can change, stated without our reasoning for it.

Two naming decisions. A repo that installs tend is a consumer, the term data/consumers.json, refresh_consumers.py, and the Worker already use — not an adopter, which the changelog keeps only in released entries. And the second kind of guidance isn't internal: a skill's metadata: internal: true already means it isn't user-invocable, and every shipped skill carries it.

Bundled and overlay

Within shipped guidance, plugins/tend-ci-runner/skills/ holds the defaults and a consumer overlays them at .claude/skills/running-tend/SKILL.md; where the two conflict, the overlay wins. .agents/skills links to .claude/skills, so Claude and Codex discover the same repo-local skills. Repo-specific policy, taste, or convention (PR title formats, label names, branch routing) goes in an overlay. Use outcomes from consumer runs to refine the defaults: a general missing instruction or wrong default is a bundled fix, repository policy an overlay one.

Tend's overlay here is tend's own guidance by the rule above — it doesn't ship, and it carries the tasks and conventions for bot sessions in this repo. A whole skill belongs there when only this repo's workflows invoke it: .claude/skills/review-reviewers/ is one, dispatched by the hand-maintained review-reviewers.yaml, whose prompt invokes it as /review-reviewers — a slash command like any skill, without the plugin prefix. A tend-only skill left in the plugin installs into every consumer, is invoked by none of them, and collects tend's internal text next to the files they do load.

Which file

Shipped or not, a rule is loaded by one set of sessions and acted on by a subset of them. Put it at the narrowest level every actor still reads: the sessions in the gap each pay attention for text that changes nothing they do.

FileRead byShips
shared/system-prompt.mdevery session, both harnessesyes
running-in-ci/SKILL.mdevery sessionyes
a workflow's SKILL.mdthat workflow's sessionsyes
a skill's references/only the sessions taking that actionyes
.claude/skills/ (the overlay, and any skill only this repo invokes)sessions in that one repono
CLAUDE.mdsessions working on the repo it sits inno
  • A rule has one home. Another file that needs it names the section instead of restating it — copies drift, and a partial copy drops what the copier left out. Before adding a rule, rg a distinctive phrase from it across plugins/, shared/, and CLAUDE.md.
  • Every workflow that invokes the agent names a skill (default_prompt in config.py). One without a skill has nowhere to put its own rules, so they land in the every-session file instead.

When reviewing or surveying a guidance file, ask both questions of it — does this ship, and who acts on it — and ask them of the sections a change leaves in place, not only the ones it touches: a restructure that moves three sections and keeps four has reviewed three.

Authoring skills

When adding to or editing files in plugins/tend-ci-runner/skills/ or .claude/skills/:

  • Be brief. Skills are loaded into every relevant session — extra prose is overhead. Lead with the rule or recipe; cut motivation, anecdotes, and historical context unless required to apply the rule.
  • The References table in running-in-ci/SKILL.md is tend-ci-runner's one index of references/ files, naming each file and the action that triggers reading it — a new bundled reference gets a row there, not a list in its own skill. A repo overlay's references stay in the overlay, named where its own steps use them: every consumer reads the bundled table, and repo-specific guidance doesn't belong in it.
  • No specific past-run references. Don't link GitHub Actions runs, cite session IDs, or quote durations from individual incidents. They age into trivia and aren't useful when the skill is reused. State the structural rule without the run links.
  • No specific past-case references. Don't cite individual past PRs, issues, or commits as supporting precedent for a rule (e.g. "[#123] tried X and was closed"). They age into trivia, accumulate as the rule is re-tested, and create read-time work. State the structural rule (what shape is accepted, what shape is not) without naming the cases that produced it.
  • Date-stamp only when the value depends on time. A baseline number expected to drift can be dated; a one-shot incident citation should not be.
  • Prefer recipe over narrative. A code block plus a one-sentence framing beats a multi-paragraph explanation.
  • Examples over templates; open frames over closed menus. For text the agent produces (comments, PR bodies, summaries), give an example labeled as such rather than verbatim wording to paste — canned phrasing reproduced literally reads awkwardly off-situation. For choices the agent makes (when to respond, which cases to check), frame the goal and give examples rather than a list it will read as exhaustive. Reserve mandatory exact wording for fragile mechanics: dedup keys, commands, API formats.

Agent-driven vs deterministic steps

Tend's workflows invoke the agent through the harness-specific composite action (max-sixty/tend/claude@X.Y.Z for Claude, max-sixty/tend/codex@X.Y.Z for Codex). When adding new capability, split work along this line:

  • The agent drives diagnostics and remediation. Once the action is running, put logic into the relevant skill (or a script the skill calls — see plugins/tend-ci-runner/scripts/). The agent handles edge cases, interprets output, and writes clearer messages than shell.
  • Actions gate whether the agent runs at all. Agent invocations cost tokens; gating them in YAML is cheap. Pre-check steps that early-exit the job (e.g. tend-notifications's notification and PR conflict check) save an entire agent run when there's nothing to do. A gate stays cheap only while it stays trivial: one pre-check against a frequent no-op (an empty inbox every cron tick) earns its place; a run of bespoke gates, each skipping one rare event shape, is machinery that costs more than the boots it saves.

Keep the actions' Bash as linear installation and plumbing, not a second implementation layer. Do not add branches, retries, caches, or state for rare event shapes or small runner-time savings; put substantial behavior in a skill or tested Python.

Don't build deterministic YAML steps for work that happens inside an agent run. Extend the skill instead.

What waste is worth fixing

Wasted runner time (a slow CI job, a run lost to a blip that a later tick retries) costs cents, while the retry wrapper, cache, or scheduling arithmetic that would prevent it is maintained forever: fix it only with a simple knob — a cadence value, a deleted step, a one-line condition — and otherwise leave it. Model tokens are the larger cost, dollars per session, so keep sessions, and the context each one carries, to what the work needs.

Judge a token saving by the share of total spend it removes. A change that materially cuts the total — a frequent boot that never had work to do, bulk reading carried into every deciding context — is worth the mechanism it leaves behind, so estimate that share before proposing one. A small or rare saving doesn't justify complication, however well the change reads line by line.

Judge the fix itself by the whole change, and by what it leaves behind — logic a future session must re-derive, a rule every later run loads, failure modes of its own — rather than by its line count. The same setting repeated across workflows, jobs, platforms, or call sites is a configuration scheme rather than one knob, and a mechanism compressed into one dense line is still a mechanism.

This is tend's answer, and it stays here. The bundled skills carry no view on what compute is worth — a bot session in this repo reads this file, and a session in another repo reads that repo's.

Live testing against real GitHub

For live experiments against real GitHub behavior (environments, branch protection, workflow triggers, secret release), tend-agent/tend-integration is a persistent public repo we own, admin via the tend-agent account (gh auth token --user tend-agent). Its main is branch-protected with enforce_admins: false, so the owner can push directly and reset in place. The weekly integration test (.claude/skills/running-tend/references/integration-test.md) also drives it, so clean up any probe artifacts (extra workflows, branches, environments, dummy secrets) when done.

Site and worker

site/ is the Astro marketing site (tend-src.com); worker/ is the Cloudflare Worker that serves its two data streams from data/consumers.json.

The site's dev server starts automatically per worktree via a wt post-start hook (.config/wt.toml) on a deterministic port derived from the branch name. Get the URL with wt list statusline --format json | jq -r '.items[].dev_server.url'; logs land in .git/wt/logs/. Don't run npm run dev; it duplicates the running server on a different port.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.