Drop Vikunja: Gitea issues are the one tracker for every agent
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m17s
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m17s
Ops work lives in one infrastructure repository for both sites, with site labels; intake, labels and dependencies work as for nisse-dev, and agent-to-agent requests are cross-repo issues. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
6e4dca040c
commit
4ca8e1f550
2 files changed
+39
-31
No files matched your search
+37
-29
@@ -138,15 +138,16 @@ Everything in this part is used by every agent.
|
||||
| **Scope** | What a work item operates on; context that outlives it | A repository | A site and service |
|
||||
|
||||
- **Sources of work items:** duties, the operator (always), and other agents. A
|
||||
request from another agent arrives through the receiving agent's normal intake
|
||||
and carries no authority of its own: the receiver applies its own rules.
|
||||
request from another agent is an issue assigned to the receiving agent, and
|
||||
carries no authority of its own: the receiver applies its own rules.
|
||||
- **A duty run is read-only;** a finding that needs attention becomes a work item,
|
||||
deduplicated by a stable fingerprint so a repeat attaches to the open item.
|
||||
- **A work item is the unit of state:** its conversation, proposals, pending
|
||||
questions, pinned roles (L9) and transcript (L7). Its locally minted ID is also
|
||||
its correlation ID in logs.
|
||||
- **An external record is linked when there is one** (a Gitea issue, a Vikunja
|
||||
ticket); external truth wins on divergence (L8).
|
||||
- **One tracker: Gitea issues,** for every agent. An issue assigned to an agent is
|
||||
a work item for it, and the issue is the item's record (D1, O5). External truth
|
||||
wins on divergence (L8).
|
||||
- **Work items don't nest:** a milestone is a phase of one; a delegation is an
|
||||
episode in one.
|
||||
|
||||
@@ -159,10 +160,11 @@ Everything in this part is used by every agent.
|
||||
| **waiting on the operator** | an answer, a go-ahead, a review or a merge |
|
||||
| **blocked** | a recorded dependency to close |
|
||||
|
||||
- **Blocked comes from external truth:** a Gitea issue dependency, or another
|
||||
agent's ticket. It becomes ready only when the dependency actually closes (P6);
|
||||
the operator can remove the dependency. An agent that finds a blocker mid-work
|
||||
proposes recording it, and records it only with the operator's agreement.
|
||||
- **Blocked comes from external truth:** a Gitea issue dependency, including on an
|
||||
issue in another repository, such as a request to another agent. It becomes
|
||||
ready only when the dependency actually closes (P6); the operator can remove the
|
||||
dependency. An agent that finds a blocker mid-work proposes recording it, and
|
||||
records it only with the operator's agreement.
|
||||
|
||||
**One active work item per agent; the rest are parked.**
|
||||
- **Switching happens only at safe points:** the active item is waiting, blocked or
|
||||
@@ -226,8 +228,8 @@ agreement: a restatement awaiting a go-ahead (D1), a design (D2), a step sequenc
|
||||
model's description (L11).
|
||||
- **Approvals expire** where the world can change underneath them (O2).
|
||||
|
||||
**Approval sources:** Matrix (L5), Gitea comments (D1) and Vikunja comments (O5),
|
||||
each checked against its own operator allowlist. The first valid approval wins and
|
||||
**Approval sources:** Matrix (L5) and Gitea comments (D1, O5), each checked
|
||||
against its own operator allowlist. The first valid approval wins and
|
||||
is echoed to the other channels. The knowledge vault is never one (L10).
|
||||
|
||||
**The trust dial:** how much the operator reviews after the fact, set by the
|
||||
@@ -293,8 +295,8 @@ verified and left open); it says what happened to a message it can't act on yet,
|
||||
rather than refusing; progress is prose at a readable rate, with raw tool activity
|
||||
on request; and it asks when unsure, including mid-implementation.
|
||||
|
||||
**Other channels:** Gitea and Vikunja carry work and records, read as structured
|
||||
JSON (never through a chat bridge). Comments from allowlisted operators are
|
||||
**Gitea carries work and records,** read as structured JSON (never through a chat
|
||||
bridge). Comments from allowlisted operators are
|
||||
instructions or approvals; anything else is data (L11).
|
||||
|
||||
**Outages delay, never fail.** Intake retries indefinitely with capped backoff and
|
||||
@@ -457,7 +459,7 @@ browses it in Obsidian.
|
||||
receive-only on it. So conflicts can't arise.
|
||||
- **Never an instruction or approval channel.** Work is never read out of the vault,
|
||||
and no agent writes there to make another act; agents coordinate through the
|
||||
operator, Matrix or tickets (L1). The operator points to a note in conversation
|
||||
operator, Matrix or issues (L1). The operator points to a note in conversation
|
||||
when it is input (L5).
|
||||
- **Corrections go through conversation** (L6). Break-glass: stop the agent, edit on
|
||||
the host, restart.
|
||||
@@ -710,13 +712,14 @@ see it or only harness operations use it (the push key). Anything the model's
|
||||
commands can see must be scoped for testing, never production.
|
||||
|
||||
**Provisioning:** build VMs come from a template via Terraform; eventually at
|
||||
`nisse-dev`'s request to `nisse-ops` (O5), until then by the operator.
|
||||
`nisse-dev`'s request to `nisse-ops` (an issue in the infrastructure repository,
|
||||
O5), until then by the operator.
|
||||
|
||||
---
|
||||
|
||||
## Part O — `nisse-ops`
|
||||
|
||||
Operates infrastructure across both sites, driven by tickets and duties, with
|
||||
Operates infrastructure across both sites, driven by issues and duties, with
|
||||
stricter controls because live changes have no review step before they take effect.
|
||||
|
||||
### O1. How it differs
|
||||
@@ -727,7 +730,7 @@ stricter controls because live changes have no review step before they take effe
|
||||
| Scope | the assigned issue and its conversation | approved step sequences (O2) |
|
||||
| Class 3 | discuss | discuss, and exact-step approval |
|
||||
| Work shape | milestones → PRs | short reactive tasks → live changes |
|
||||
| Intake | Gitea issues, Matrix | Vikunja tickets, alerts, duties, Matrix |
|
||||
| Intake | issues in the project's repository, Matrix | issues in the infrastructure repository, alerts, duties, Matrix |
|
||||
| Reach | sealed build VMs | Tailscale, credentials, both sites |
|
||||
|
||||
They are separate deployments over one library; one instance playing both would
|
||||
@@ -766,8 +769,8 @@ template with a trigger, rate limit and expiry, for a routine fix).
|
||||
|
||||
| Class | Examples |
|
||||
|---|---|
|
||||
| 1 | Metrics, logs, status, read-only MCP calls, tickets, the world model |
|
||||
| 2 (in scope) | Approved steps with a known undo; its own world model and tickets |
|
||||
| 1 | Metrics, logs, status, read-only MCP calls, issues, the world model |
|
||||
| 2 (in scope) | Approved steps with a known undo; its own world model; commenting on and filing issues in the infrastructure repository |
|
||||
| 3 | Every other infrastructure write; browser actions on admin UIs (each confirmed); **anything on network gear**, the most conservative case, since a bad change can sever the path to fix it |
|
||||
|
||||
### O4. Interfaces
|
||||
@@ -778,15 +781,20 @@ template with a trigger, rate limit and expiry, for a routine fix).
|
||||
- **Event intake** as structured JSON (directly or via Alertmanager); curated
|
||||
updates go to `#ops`.
|
||||
|
||||
### O5. Tickets and duties
|
||||
### O5. Issues and duties
|
||||
|
||||
- **A Vikunja ticket is a work item's record;** Matrix is the live conversation.
|
||||
Flow: filed → picked up → discussed → status updates → closed with the result.
|
||||
- **Tickets that trigger action are operator-scoped.** Tickets from duties (findings)
|
||||
and from other agents' requests (L1, e.g. `nisse-dev` asking for a build VM) may
|
||||
be picked up and planned, but any write needs a step sequence the operator
|
||||
approves. Until standing approvals exist, that means every provisioning request.
|
||||
- **Vikunja comments approve plans on their own ticket** (`approve rev-N`).
|
||||
- **One infrastructure repository for both sites,** holding ops' issues (it need
|
||||
hold no code). Sites are labels (`garrett-hall`, `hartman-hut`), so cross-site
|
||||
work is one issue. Intake works as in D1: an issue assigned to the ops agent is a
|
||||
work item and its record, labels steer, and Gitea dependencies mark it blocked.
|
||||
Matrix is the live conversation.
|
||||
- **Action is operator-scoped.** Issues from duties (findings, opened by ops itself
|
||||
and deduplicated by fingerprint) and requests from other agents (L1, e.g.
|
||||
`nisse-dev` asking for a build VM, which then waits blocked on that issue) may be
|
||||
picked up and planned, but any write needs a step sequence the operator approves
|
||||
(O2). Until standing approvals exist, that means every provisioning request.
|
||||
- **Comments on the issue approve its plan** (`approve rev-N`), as an alternative to
|
||||
Matrix (L3).
|
||||
|
||||
### O6. Deployment
|
||||
|
||||
@@ -855,7 +863,7 @@ so every upstream action traces to one agent.
|
||||
### X5. Supporting services
|
||||
|
||||
All self-hosted: Matrix (Synapse), Gitea, LiteLLM, the local inference host,
|
||||
Vikunja, Vaultwarden, LLDAP with Authelia, and Syncthing for the operator's copy of
|
||||
Vaultwarden, LLDAP with Authelia, and Syncthing for the operator's copy of
|
||||
the vault. Each agent has its own account, token and room in each; nothing is
|
||||
shared between agents.
|
||||
|
||||
@@ -872,8 +880,8 @@ shared between agents.
|
||||
- **More than one active work item:** needs per-item serialisation, an inference
|
||||
scheduler and per-item intents. Build VMs and threads already separate workspaces
|
||||
and conversations.
|
||||
- **Whether pure conversations need an external record** (dev work on a repository
|
||||
and ops tickets already have one).
|
||||
- **Whether pure conversations need an external record** (work on a repository
|
||||
already has its issue).
|
||||
- **Stacked PRs:** starting a milestone before the previous one merges, after
|
||||
experience with waiting (D4).
|
||||
- **Build VM collection:** how long idle, and whether it needs the operator's word.
|
||||
|
||||
@@ -321,8 +321,8 @@ if the implementation differs.
|
||||
on the operator defaults to 10 minutes. When the driver chooses the next ready
|
||||
item and the choice fails or is invalid, fall back to the oldest.
|
||||
- **L3 revision stamping:** in Matrix, a reply is stamped with the revision whose
|
||||
message had been sent when it arrived; on a Gitea issue or a Vikunja ticket,
|
||||
with the latest proposal comment older than the reply.
|
||||
message had been sent when it arrived; on a Gitea issue, with the latest
|
||||
proposal comment older than the reply.
|
||||
- **L5 transport:** the `Transport` interface is send, ask and receive. Intake
|
||||
backoff is exponential, capped at a few minutes.
|
||||
- **L6 fitting order:** first shorten old tool results to their first and last
|
||||
|
||||
Reference in new issue
Block a user