---
title: Watch repository and dependency changes
description: Turn repository drift and upstream releases into evidence for new issues.
---

Repository care and release watching feed the same intake process. Each
monitor records a signal and an assessment. A person decides whether it
warrants an issue, adds acceptance criteria, and marks the issue ready.

This module can run independently of the issue walkthrough. Complete
[agent setup](/marbles/get-started/installation#add-optional-capabilities-when-needed)
and run it from the repository you want to inspect.

These monitors gather signals. The [inspector](/marbles/use-cases/software-factory/improvement/inspector)
connects them to failed checks and earlier decisions before proposing an
improvement. Use [skill evaluations](/marbles/use-cases/evaluations/skills)
when the change concerns the instructions agents follow.

## Watch repository instructions

The first monitor below watches `AGENTS.md` and `CLAUDE.md`. It asks an agent
to read the changed instructions and relevant Git history, then stores its
findings in an artifact. This is the repository caretaker's role in the factory.

## Watch upstream releases

The second monitor polls Bun's release metadata. It compares release tags
before asking for an assessment, so unrelated metadata changes do not
repeat the agent work. Change the source for another dependency.

Create `.foundry/marbles/maintenance.ts`:

<details>
<summary>Complete maintenance.ts</summary>

```ts
import { agent, artifact, monitor } from "@foundry.sh/marbles";

const signals = artifact({
  name: "Factory maintenance signals",
  type: "application/json",
});
const assessor = agent({
  prompt:
    "Assess this change against the repository. Describe the evidence, whether an issue is warranted, and suggested acceptance criteria. Do not edit files or create an issue.",
});

monitor("**/{AGENTS,CLAUDE}.md")
  .every("1m")
  .do(async ({ files, agents, report, run }) => {
    const session = await agents.session(assessor);
    const reply = await session.generate(
      `Inspect instruction drift and relevant Git history: ${JSON.stringify(files)}`
    );
    await report.artifact(
      signals,
      {
        "assessment.md": reply.text,
        "signal.json": JSON.stringify(
          { files, runId: run.id, source: "repository instructions" },
          null,
          2
        ),
      },
      { body: reply.text, title: "Repository instruction assessment" }
    );
  });

const releaseTag = (value: unknown): string | undefined => {
  if (typeof value !== "object" || value === null || !("tag_name" in value)) {
    return;
  }
  return typeof value.tag_name === "string" ? value.tag_name : undefined;
};
monitor("https://api.github.com/repos/oven-sh/bun/releases/latest")
  .every("6h")
  .do(async ({ change, agents, report, run }) => {
    if (change.kind !== "http") {
      return;
    }
    const tag = releaseTag(change.current);
    if (!tag || tag === releaseTag(change.previous)) {
      return;
    }
    const session = await agents.session(assessor);
    const reply = await session.generate(
      `Assess Bun ${tag} for this repository. Read its release notes before proposing upgrade work.`
    );
    await report.artifact(
      signals,
      {
        "assessment.md": reply.text,
        "signal.json": JSON.stringify(
          { runId: run.id, source: "Bun release", tag },
          null,
          2
        ),
      },
      { body: reply.text, title: `Bun ${tag} assessment` }
    );
  });
```

</details>

## Bring a signal into the cycle

Run `marbles list` to find each monitor key, then `marbles roll <key>` for
one poll. The first poll sees the existing files or release as a change.
Read the assessment in the Feed before enabling the monitor loop.

When an assessment warrants work, create or update an issue with the
source, artifact version, relevant findings, and acceptance criteria.
For a release, include the release tag. For instruction drift, identify
the changed files and repository revision. That evidence becomes part of
the issue snapshot and stays available to the implementer and reviewer.

The `Factory maintenance signals` artifact keeps a version per assessment.
Each `report.artifact(...)` call supplies the assessment as its Feed body,
so a person can read it there. The saved `signal.json` and `assessment.md`
retain the evidence for the issue and later runs.
Its latest version is the most recent signal, so retain the specific
version ID in the issue. It is not a queue of all unhandled signals.

A failed handler can observe the same change again. Check for an existing
issue before filing another one. Dry execution still reads files and sends
the HTTP request, while it substitutes the agent turn.

Next: [Schedule updates and reports](/marbles/use-cases/software-factory/maintenance/automate).
