Set up, understand, and change a Tessl factory on a repository: pick automations that fit how you work, such as shipping tickets as pull requests, answering reviews and fixing checks on those pull requests, code review, and scheduled jobs; prepare the repository for agents; write issues for the factory to build; then see what the factory has done, find out why a run failed or never started, and change or extend it.
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Answer the person's question about the factory on this repository from what
Tessl and GitHub record, and say what would let the work continue. This skill
only reads: change nothing in tessl.json, the cloud environment, the Loops,
GitHub, or Linear. When a fix is needed, name it and leave it to the person.
The person has an answer they can act on:
webUrl) and to
each issue and pull request;date -u before you start.From the repository root:
tessl project repair --json: linkedProject.id is the project,
linkedProject.workspaceName its workspace, and webUrl with /loops
added is its Loops page. No linked project
means no factory is set up for this repository; say so, offer the
factory-setup skill, and stop.tessl schedule list --project-id <project id> --all --json lists the
project's Loops, which are its automations. attributes.definitionSource
is app for one set up in Tessl directly (usually "ship tickets", "answer
reviews and fix checks", "follow ticket changes", "fix merge conflicts",
and Learn from past work)
and repo for one from tessl.json. attributes.label is its name,
attributes.status is active or paused, each entry's name in
attributes.triggers[] is a trigger that starts it, and
attributes.lastRunAt and attributes.runCount say when it last ran and
how often. tessl schedule view <loop id> --json gives its skill, model,
and environment. When the person names an automation, match it here.tessl.json: its actions, triggers, and schedules are the
automations defined in the repository. An action in tessl.json with no
Loop means Tessl has not processed the file: run tessl schedule list without --json and
check its sync warning. tessl schedule validate checks only the
schedules block; tessl doctor --automations checks the whole
configuration.--org take the project's organization: environment.attributes.orgId in
tessl environment view <environment> --json, for an environment a Loop
uses.Each run records the workspace, the repository it ran on
(attributes.config.repoUrl), its skill (attributes.config.skillRef), what
started it (attributes.label, such as github-issue-labelled #3 @ada or
shepherd-checks-passed #8), its status, the agent's outcome, and a
one-line summary.
tessl launch list --link-type github_issue|github_pr|linear_issue --link-value <its URL> --limit 100 --json.
A run is linked to the issue or pull request whose event started it as soon
as it is created, so a run that failed early is still listed. For an issue,
the runs on its pull request are linked to the pull request, not the issue:
read the implementation run's links with tessl launch view <id> --json,
where the one in data.attributes.links[] with rel produced is the pull
request it opened, then list that pull request's runs too.tessl launch list --workspace <workspace> --since <UTC ISO time> --limit 100 --json, then the next page
with --after <nextCursor> until nextCursor is null. The listing covers
the whole workspace: keep only the runs whose config.repoUrl is this
repository. Use the period the person names, or the last 7 days and say so.--status pending.tessl launch view <id> --json for its record and links, and
tessl launch view <id> without --json for its credit cost, which only
that output shows.Read GitHub alongside: the issue's and pull request's comments
(gh issue view <n> --comments, gh pr view <n> --comments), the pull
request's state and checks. Tessl's own comments end with
<!-- tessl-factory -->; a question the agent asked also has
<!-- tessl-factory:question -->.
Take the first situation that applies.
outcome.status is succeeded. The agent did its job.
Say what, from summary and the links: the pull request it opened, the
review it answered, the note it posted.no_action. The agent looked and found nothing to do,
for example a pull request with no new feedback and checks still running.
This is normal; say why from summary.needs_input, or the issue has an unanswered
tessl-factory:question comment. The work is waiting on a person. Quote
the question and say how to continue: reply on the issue, and if nothing
starts, remove the label and add it again.failed, or no outcome. The agent stopped without
finishing. Give outcome.reason in plain words.failed. The run itself failed. Read
tessl launch progress <id> --filename prepare-subphases.json:
first_failed names the step that failed before the agent started.
cloud-launch-setup means the repository's setup hook,
.tessl/cloud-launch-setup.sh, failed; clone (getting the repository),
manifest-sync (syncing its config) and skill-install (installing the
skill) name those steps, and you say them in those words. Give
data.attributes.failureReason.message, or its code, and the failing
command from failureReason.details when it is there; only workspace admins
see details. No first_failed means the agent started and then failed:
read the transcript.cancelled. Someone or something stopped it, usually the "follow
ticket changes" automation after a person took the issue back. Look for
its "Stopped" note on the issue.pending. Check it again a minute later. While a run is working,
Tessl updates progressUpdatedAt about every 30 seconds. A pending run
whose progressUpdatedAt is more than 5 minutes old has shown no progress
since then: it may be stuck, or retrying. Say only that, with its link,
and check again. If it is still pending with no new progress 10 minutes
later, say Tessl support can look at it. One with no progressUpdatedAt
may still be queued behind another run on the same issue or pull
request.Then look at where the work stands now, because every run can have done its
job while the work has stalled. When the latest run says it is waiting for
something, such as checks still running, check whether that has happened and
whether the result matches one of the automation's triggers. The shepherd wakes on a
check that fails (failure, timed_out, startup_failure,
action_required) and on a check suite that succeeds. A canceled check is
neither, and its suite does not succeed, so a pull request whose checks were
canceled gets no further runs and no "ready for review" note. gh pr checks
shows a canceled check as fail; read the real conclusion from
gh api repos/<owner>/<repo>/commits/<head sha>/check-runs. Say what would
start the next run, such as re-running the checks.
For situations 4 and 5, and whenever the summary does not explain the
outcome, read the transcript: tessl launch logs <id> > <file>, then the
last messages and tool calls in it. It says "no agent logs have been
uploaded" when the agent never started or the upload failed.
No run is linked to the issue or pull request. Check, in this order, and stop at the first that explains it:
paused (step 1).when: in tessl.json, or, for a Loop set up in Tessl, in
attributes.triggers of tessl schedule view <loop id> --json:
tessl. To tell "never labeled" from
"labeled, then removed", read the issue's label events:
gh api repos/<owner>/<repo>/issues/<n>/timeline --paginate --jq '.[] | select(.event=="labeled" or .event=="unlabeled") | {event, label: .label.name, actor: .actor.login, created_at}';event.sender.id, when the trigger has it. A list of IDs (a single
ID or in) means only those GitHub users can start it,
so a teammate's label or comment starts nothing until their ID is added
(gh api users/<login> --jq .id). not with
{{ github.tesslApp.userId }} means anyone but the Tessl app can;event.sender.type, when the trigger has it: not with Bot means
nothing a bot does starts it, so a review from Tessl Reviewer or another
review bot starts nothing;event.issue.state or event.pull_request.state: closed issues and pull
requests start nothing;head.repo.id and head.ref: only pull requests on a tessl/ branch of
this repository, not a fork, start the shepherd.tessl doctor --automations, Event
delivery: it reports when the Tessl app cannot see the repository or no
event has arrived.tessl org list --json, the organization's
usage.credits: blocked true means runs cannot start. A negative
remaining with blocked false still runs.If none explains it, say what you checked and that the cause is unknown.
When the person asks what the factory has done, group the runs by
automation, using each run's config.skillRef and the Loop that runs that
skill. A run started by hand, such as the setup check, has a
plain label and no trigger: list it separately as a one-off. For each
automation, give:
tessl launch view <id> --json, as in step 2), and whether each is open or
merged (gh pr view <url> --json state);Give credits only when asked, or for the runs you are explaining: the cost of
each run is in tessl launch view <id>, and the organization's balance is
usage.credits.remaining in tessl org list --json. When the period has many
runs, say the total would take one lookup per run and offer to do it.
End with what else Tessl could do for this repository, in two or three
lines. When Learn from past work is not set up (no Loop or schedule in
tessl.json runs a tessl-labs/learn-from-past-work skill, or one of its
tessl-labs/improve-development skills from before, worked out as
"Which skill a schedule runs" on
the features page says), lead
with it: it reads each
week's reviews and runs and records the mistakes that keep recurring, with
the cheapest fix. When it is set up, give the number of open findings from
tessl finding list --project <project id> --state open --json, and offer to
go through them. Then, if this period's runs point to one, name one more feature that is
off, from
the features page, such as a
review lens for a comment reviewers kept repeating. Say the change-factory
skill can set any of them up.
Then ask whether they want to look into anything in it.