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 |
|
| **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
|
- **Sources of work items:** duties, the operator (always), and other agents. A
|
||||||
request from another agent arrives through the receiving agent's normal intake
|
request from another agent is an issue assigned to the receiving agent, and
|
||||||
and carries no authority of its own: the receiver applies its own rules.
|
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,
|
- **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.
|
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
|
- **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
|
questions, pinned roles (L9) and transcript (L7). Its locally minted ID is also
|
||||||
its correlation ID in logs.
|
its correlation ID in logs.
|
||||||
- **An external record is linked when there is one** (a Gitea issue, a Vikunja
|
- **One tracker: Gitea issues,** for every agent. An issue assigned to an agent is
|
||||||
ticket); external truth wins on divergence (L8).
|
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
|
- **Work items don't nest:** a milestone is a phase of one; a delegation is an
|
||||||
episode in one.
|
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 |
|
| **waiting on the operator** | an answer, a go-ahead, a review or a merge |
|
||||||
| **blocked** | a recorded dependency to close |
|
| **blocked** | a recorded dependency to close |
|
||||||
|
|
||||||
- **Blocked comes from external truth:** a Gitea issue dependency, or another
|
- **Blocked comes from external truth:** a Gitea issue dependency, including on an
|
||||||
agent's ticket. It becomes ready only when the dependency actually closes (P6);
|
issue in another repository, such as a request to another agent. It becomes
|
||||||
the operator can remove the dependency. An agent that finds a blocker mid-work
|
ready only when the dependency actually closes (P6); the operator can remove the
|
||||||
proposes recording it, and records it only with the operator's agreement.
|
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.**
|
**One active work item per agent; the rest are parked.**
|
||||||
- **Switching happens only at safe points:** the active item is waiting, blocked or
|
- **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).
|
model's description (L11).
|
||||||
- **Approvals expire** where the world can change underneath them (O2).
|
- **Approvals expire** where the world can change underneath them (O2).
|
||||||
|
|
||||||
**Approval sources:** Matrix (L5), Gitea comments (D1) and Vikunja comments (O5),
|
**Approval sources:** Matrix (L5) and Gitea comments (D1, O5), each checked
|
||||||
each checked against its own operator allowlist. The first valid approval wins and
|
against its own operator allowlist. The first valid approval wins and
|
||||||
is echoed to the other channels. The knowledge vault is never one (L10).
|
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
|
**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
|
rather than refusing; progress is prose at a readable rate, with raw tool activity
|
||||||
on request; and it asks when unsure, including mid-implementation.
|
on request; and it asks when unsure, including mid-implementation.
|
||||||
|
|
||||||
**Other channels:** Gitea and Vikunja carry work and records, read as structured
|
**Gitea carries work and records,** read as structured JSON (never through a chat
|
||||||
JSON (never through a chat bridge). Comments from allowlisted operators are
|
bridge). Comments from allowlisted operators are
|
||||||
instructions or approvals; anything else is data (L11).
|
instructions or approvals; anything else is data (L11).
|
||||||
|
|
||||||
**Outages delay, never fail.** Intake retries indefinitely with capped backoff and
|
**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.
|
receive-only on it. So conflicts can't arise.
|
||||||
- **Never an instruction or approval channel.** Work is never read out of the vault,
|
- **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
|
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).
|
when it is input (L5).
|
||||||
- **Corrections go through conversation** (L6). Break-glass: stop the agent, edit on
|
- **Corrections go through conversation** (L6). Break-glass: stop the agent, edit on
|
||||||
the host, restart.
|
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.
|
commands can see must be scoped for testing, never production.
|
||||||
|
|
||||||
**Provisioning:** build VMs come from a template via Terraform; eventually at
|
**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`
|
## 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.
|
stricter controls because live changes have no review step before they take effect.
|
||||||
|
|
||||||
### O1. How it differs
|
### 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) |
|
| Scope | the assigned issue and its conversation | approved step sequences (O2) |
|
||||||
| Class 3 | discuss | discuss, and exact-step approval |
|
| Class 3 | discuss | discuss, and exact-step approval |
|
||||||
| Work shape | milestones → PRs | short reactive tasks → live changes |
|
| 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 |
|
| Reach | sealed build VMs | Tailscale, credentials, both sites |
|
||||||
|
|
||||||
They are separate deployments over one library; one instance playing both would
|
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 |
|
| Class | Examples |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 1 | Metrics, logs, status, read-only MCP calls, tickets, the world model |
|
| 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 and tickets |
|
| 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 |
|
| 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
|
### 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
|
- **Event intake** as structured JSON (directly or via Alertmanager); curated
|
||||||
updates go to `#ops`.
|
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.
|
- **One infrastructure repository for both sites,** holding ops' issues (it need
|
||||||
Flow: filed → picked up → discussed → status updates → closed with the result.
|
hold no code). Sites are labels (`garrett-hall`, `hartman-hut`), so cross-site
|
||||||
- **Tickets that trigger action are operator-scoped.** Tickets from duties (findings)
|
work is one issue. Intake works as in D1: an issue assigned to the ops agent is a
|
||||||
and from other agents' requests (L1, e.g. `nisse-dev` asking for a build VM) may
|
work item and its record, labels steer, and Gitea dependencies mark it blocked.
|
||||||
be picked up and planned, but any write needs a step sequence the operator
|
Matrix is the live conversation.
|
||||||
approves. Until standing approvals exist, that means every provisioning request.
|
- **Action is operator-scoped.** Issues from duties (findings, opened by ops itself
|
||||||
- **Vikunja comments approve plans on their own ticket** (`approve rev-N`).
|
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
|
### O6. Deployment
|
||||||
|
|
||||||
@@ -855,7 +863,7 @@ so every upstream action traces to one agent.
|
|||||||
### X5. Supporting services
|
### X5. Supporting services
|
||||||
|
|
||||||
All self-hosted: Matrix (Synapse), Gitea, LiteLLM, the local inference host,
|
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
|
the vault. Each agent has its own account, token and room in each; nothing is
|
||||||
shared between agents.
|
shared between agents.
|
||||||
|
|
||||||
@@ -872,8 +880,8 @@ shared between agents.
|
|||||||
- **More than one active work item:** needs per-item serialisation, an inference
|
- **More than one active work item:** needs per-item serialisation, an inference
|
||||||
scheduler and per-item intents. Build VMs and threads already separate workspaces
|
scheduler and per-item intents. Build VMs and threads already separate workspaces
|
||||||
and conversations.
|
and conversations.
|
||||||
- **Whether pure conversations need an external record** (dev work on a repository
|
- **Whether pure conversations need an external record** (work on a repository
|
||||||
and ops tickets already have one).
|
already has its issue).
|
||||||
- **Stacked PRs:** starting a milestone before the previous one merges, after
|
- **Stacked PRs:** starting a milestone before the previous one merges, after
|
||||||
experience with waiting (D4).
|
experience with waiting (D4).
|
||||||
- **Build VM collection:** how long idle, and whether it needs the operator's word.
|
- **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
|
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.
|
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
|
- **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,
|
message had been sent when it arrived; on a Gitea issue, with the latest
|
||||||
with the latest proposal comment older than the reply.
|
proposal comment older than the reply.
|
||||||
- **L5 transport:** the `Transport` interface is send, ask and receive. Intake
|
- **L5 transport:** the `Transport` interface is send, ask and receive. Intake
|
||||||
backoff is exponential, capped at a few minutes.
|
backoff is exponential, capped at a few minutes.
|
||||||
- **L6 fitting order:** first shorten old tool results to their first and last
|
- **L6 fitting order:** first shorten old tool results to their first and last
|
||||||
|
|||||||
Reference in new issue
Block a user