Write the agreed dev workflow into the architecture
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m19s
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m19s
Issues assigned to dev-agent are the intake; the agent restates its understanding and either proceeds (bug label) or waits for a go-ahead. Labels steer and are never required. Build plans and ARCHITECTURE.md are working documents reviewed in PRs, not gates; scope is the issue and its conversation. Work items can be blocked on Gitea dependencies, each gets a Matrix thread, milestones are started and finished by control tools, and the next milestone waits for the previous merge. 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
3e7edce6dc
commit
cd2ff6d769
1 file changed
+170
-74
+170
-74
@@ -93,12 +93,13 @@ Every action any agent can take falls into one of three classes:
|
|||||||
| Class | What it is | Examples | Rule |
|
| Class | What it is | Examples | Rule |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| **1. No side effects** | Observes; changes nothing outside a disposable sandbox | Reading files, querying APIs, searching, viewing logs and metrics, running a build or tests in a throwaway environment | Always allowed |
|
| **1. No side effects** | Observes; changes nothing outside a disposable sandbox | Reading files, querying APIs, searching, viewing logs and metrics, running a build or tests in a throwaway environment | Always allowed |
|
||||||
| **2. Contained side effects** | Changes something, but the change stays within the agent's own area or has a known undo | Editing the workspace, committing to the agent's branch, opening a PR, writing the agent's own notes, starting a test container; for ops, a step with a known undo inside an approved plan | Allowed when in scope; logged and reported |
|
| **2. Contained side effects** | Changes something, but the change stays within the agent's own area or has a known undo | Editing the workspace, committing to the agent's branch, opening a PR, writing the agent's own notes, starting a test container; for ops, a step with a known undo inside an approved step sequence | Allowed when in scope; logged and reported |
|
||||||
| **3. Dangerous** | Irreversible, visible beyond the agent's own area, or outside what was agreed | Merging to a default branch, deleting data, changing a firewall, installing software on a host the agent doesn't own, contacting third parties, spending beyond a budget | Needs discussion, unless an approved plan names the exact action |
|
| **3. Dangerous** | Irreversible, visible beyond the agent's own area, or outside what was agreed | Merging to a default branch, deleting data, changing a firewall, installing software on a host the agent doesn't own, contacting third parties, spending beyond a budget | Needs discussion, unless an approved step sequence (O2) or the operator in conversation names the exact action |
|
||||||
|
|
||||||
**"In scope"** means within what the operator agreed to: the work item's task,
|
**"In scope"** means within what the operator agreed to: the work item's task
|
||||||
an approved plan, a pre-approved milestone (D2), or an approved step sequence
|
and what was agreed in its conversation (for `nisse-dev`, the assigned issue,
|
||||||
(O2). An action can be class 2 in one work item and class 3 in another.
|
D1), or an approved step sequence (O2). An action can be class 2 in one work item
|
||||||
|
and class 3 in another.
|
||||||
|
|
||||||
**Move actions down the classes wherever it is cheap.** Reversibility is designed
|
**Move actions down the classes wherever it is cheap.** Reversibility is designed
|
||||||
in, not hoped for (P5).
|
in, not hoped for (P5).
|
||||||
@@ -191,7 +192,7 @@ Every agent's work is organised into three kinds of unit.
|
|||||||
|
|
||||||
| Concept | What it is | Lifetime | `nisse-dev` | `nisse-ops` |
|
| Concept | What it is | Lifetime | `nisse-dev` | `nisse-ops` |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **Duty** | A standing responsibility that produces work items | Recurring | None yet; the operator is the only source | Scheduled checks, log monitoring, alert intake |
|
| **Duty** | A standing responsibility that produces work items | Recurring | Gitea issues assigned to `dev-agent` (D1) | Scheduled checks, log monitoring, alert intake |
|
||||||
| **Work item** | One effort, opened and eventually closed | Opened → closed | Building a feature in a repo | Diagnosing a failure; making one change |
|
| **Work item** | One effort, opened and eventually closed | Opened → closed | Building a feature in a repo | Diagnosing a failure; making one change |
|
||||||
| **Scope** | What a work item operates on, and the context that persists across work items there | Indefinite | A repo | A site and service, e.g. `garrett-hall` Proxmox |
|
| **Scope** | What a work item operates on, and the context that persists across work items there | Indefinite | A repo | A site and service, e.g. `garrett-hall` Proxmox |
|
||||||
|
|
||||||
@@ -217,6 +218,22 @@ Every agent's work is organised into three kinds of unit.
|
|||||||
- **Scopes hold context shared across work items** (L6): for a repo, its documents
|
- **Scopes hold context shared across work items** (L6): for a repo, its documents
|
||||||
and conventions; for infrastructure, the world model of that site or service.
|
and conventions; for infrastructure, the world model of that site or service.
|
||||||
|
|
||||||
|
**Work item states.**
|
||||||
|
|
||||||
|
| State | Waiting for |
|
||||||
|
|---|---|
|
||||||
|
| **active** | nothing; it is being worked on |
|
||||||
|
| **ready** | its turn |
|
||||||
|
| **waiting on the operator** | an answer, a review or an approval |
|
||||||
|
| **blocked** | something else to finish, e.g. another issue to close |
|
||||||
|
|
||||||
|
- **Blocked is read from external truth,** such as a Gitea issue dependency (D1),
|
||||||
|
and becomes ready only when that dependency actually closes, never by a model's
|
||||||
|
judgement (P6). The operator can unblock by removing the dependency.
|
||||||
|
- **An agent that finds a blocker mid-work** says so and proposes recording it
|
||||||
|
(e.g. "blocked by #12"); with the operator's agreement it records it, parks the
|
||||||
|
item as blocked and moves on.
|
||||||
|
|
||||||
**Park-and-switch: one active work item per agent.**
|
**Park-and-switch: one active work item per agent.**
|
||||||
- Other work items are *parked*, with their full position held durably.
|
- Other work items are *parked*, with their full position held durably.
|
||||||
- **Switching happens only at safe points,** when the active item is waiting on
|
- **Switching happens only at safe points,** when the active item is waiting on
|
||||||
@@ -225,10 +242,12 @@ Every agent's work is organised into three kinds of unit.
|
|||||||
item (one it can act on without the operator) when the active item is waiting on
|
item (one it can act on without the operator) when the active item is waiting on
|
||||||
the operator, after a grace period (default 10 minutes, so a watching operator
|
the operator, after a grace period (default 10 minutes, so a watching operator
|
||||||
can answer first), or has closed.
|
can answer first), or has closed.
|
||||||
- **The driver chooses which ready item,** from code-rendered summaries (source,
|
- **Which ready item comes next:** the operator's order when given (e.g. "do #14
|
||||||
age, severity, state, title), never from other items' transcripts. A failed or
|
next", or a priority label); otherwise the oldest ready item. An agent may instead
|
||||||
invalid choice falls back to the oldest ready item. Choosing grants nothing: every
|
let the driver choose from code-rendered summaries (source, age, severity, state,
|
||||||
item still meets its own rules.
|
title), never from other items' transcripts, where judgement helps (`nisse-ops`,
|
||||||
|
where severity matters); a failed or invalid choice falls back to the oldest.
|
||||||
|
Choosing grants nothing: every item still meets its own rules.
|
||||||
- **Parking gives up authority.** Elevated credentials an item's plan mounted
|
- **Parking gives up authority.** Elevated credentials an item's plan mounted
|
||||||
(O2, X3) are unmounted when it parks, and remounted only if its approval hasn't
|
(O2, X3) are unmounted when it parks, and remounted only if its approval hasn't
|
||||||
expired.
|
expired.
|
||||||
@@ -268,17 +287,21 @@ Rules for the loop:
|
|||||||
|
|
||||||
### L3. Authority: approvals and permissions
|
### L3. Authority: approvals and permissions
|
||||||
|
|
||||||
An approval grants a **permission with a scope**: "this build plan may change
|
An approval grants a **permission with a scope**: "work on this issue",
|
||||||
this repo", "these ops steps may run", "this milestone may proceed without
|
"these ops steps may run". Actions are checked against the permissions in force
|
||||||
discussion". Actions are checked against the permissions in force (P3); the loop
|
(P3); the loop does not stop at gates for their own sake.
|
||||||
does not stop at gates for their own sake.
|
|
||||||
|
|
||||||
**What needs discussion before it happens:**
|
**Where scope comes from.**
|
||||||
- **Architecture documents and build plans are always discussed** with the
|
- **For dev work:** the assigned issue and what the operator agreed in its
|
||||||
operator (D2). Their approval is the scope for the work that follows.
|
conversation (D1). Build plans are the agent's working documents, not approvals
|
||||||
- A build plan marks each milestone **pre-approved** (proceed when reached) or
|
(D2); the operator's real check is reviewing the PR, and nothing merges without
|
||||||
**needs discussion** (stop and talk first).
|
it unless the trust dial says so.
|
||||||
- **Any class-3 action** not named by an approved plan (P3).
|
- **For ops work:** an approved step sequence (O2), which is exact.
|
||||||
|
- **The operator steers with labels and words, never required ones** (D1): a label
|
||||||
|
or a request can ask the agent to talk first; leaving one off is never an error.
|
||||||
|
|
||||||
|
**What always needs discussion first:** any class-3 action not named by an
|
||||||
|
approved step sequence or by the operator in conversation (P3).
|
||||||
|
|
||||||
**Approvals bind to exactly what was approved.**
|
**Approvals bind to exactly what was approved.**
|
||||||
- Every plan revision carries a tag, numbered across the whole work item, so
|
- Every plan revision carries a tag, numbered across the whole work item, so
|
||||||
@@ -300,10 +323,9 @@ allowlist. The first valid approval wins and is echoed to the other channels. Th
|
|||||||
knowledge vault (L10) is **never** an approval source or an instruction channel.
|
knowledge vault (L10) is **never** an approval source or an instruction channel.
|
||||||
|
|
||||||
**The trust dial.** How much the operator reviews after the fact is **data the
|
**The trust dial.** How much the operator reviews after the fact is **data the
|
||||||
operator sets**, per project and per milestone: for example, whether PR review is
|
operator sets**, per project: for example, whether PR review is required before
|
||||||
required before merging, or whether the agent may merge a pre-approved milestone
|
merging, or whether the agent may merge its own PRs once checks pass. The operator
|
||||||
itself once checks pass. The operator turns it up as confidence grows. The agent
|
turns it up as confidence grows. The agent never changes it.
|
||||||
never changes it.
|
|
||||||
|
|
||||||
### L4. The action classifier
|
### L4. The action classifier
|
||||||
|
|
||||||
@@ -317,7 +339,8 @@ An independent check that sorts an action the fast path doesn't cover.
|
|||||||
**Rules:**
|
**Rules:**
|
||||||
- **It judges the action, not the actor's story.** Its input is the structured
|
- **It judges the action, not the actor's story.** Its input is the structured
|
||||||
action (tool, command, target, a summary of the change) and the **agreed scope**
|
action (tool, command, target, a summary of the change) and the **agreed scope**
|
||||||
(the work item's task, the approved plan or milestone). Never the actor's
|
(the work item's task and what was agreed, or the approved step sequence). Never
|
||||||
|
the actor's
|
||||||
transcript or reasoning, and never untrusted content such as issue text or web
|
transcript or reasoning, and never untrusted content such as issue text or web
|
||||||
pages. Otherwise injected text, or the actor's own rationalisation, can argue past
|
pages. Otherwise injected text, or the actor's own rationalisation, can argue past
|
||||||
it.
|
it.
|
||||||
@@ -342,7 +365,18 @@ Existing Matrix clients are the UI.
|
|||||||
|
|
||||||
**What the operator can say.** Plain language, plus a small command vocabulary
|
**What the operator can say.** Plain language, plus a small command vocabulary
|
||||||
that works in every state: `status`, `stop`, `abandon`, `approve [rev-N]`, and
|
that works in every state: `status`, `stop`, `abandon`, `approve [rev-N]`, and
|
||||||
work-item selection (e.g. `use <project>`).
|
work-item selection (e.g. `use <project>`, "do #14 next").
|
||||||
|
- **Free-flowing conversation can open a work item.** A conversation about work
|
||||||
|
("I'm having trouble with X…") is kept as a work item from its first message; it
|
||||||
|
may end with a project, an issue, or just an answer.
|
||||||
|
- **A thread per work item.** The agent opens each work item's conversation as a
|
||||||
|
Matrix thread. A reply in a thread goes to that item, even while it is parked
|
||||||
|
(answering makes it ready); top-level messages go to the agent in general or to
|
||||||
|
the active item.
|
||||||
|
- **Documents as input.** The operator can paste a document, attach a text or
|
||||||
|
Markdown file, or point to a note in the knowledge vault (L10) ("my sketch is in
|
||||||
|
the vault as `recipes idea`"). The message is the instruction; the document is
|
||||||
|
material for the conversation.
|
||||||
- **Commands are matched without regard to case, surrounding whitespace, trailing
|
- **Commands are matched without regard to case, surrounding whitespace, trailing
|
||||||
punctuation, or a leading mention of the agent.** Messages that begin by
|
punctuation, or a leading mention of the agent.** Messages that begin by
|
||||||
addressing someone else are not for this agent.
|
addressing someone else are not for this agent.
|
||||||
@@ -382,7 +416,7 @@ What each model sees, what persists, and how memory is written and used.
|
|||||||
for one role, fitted to that model's window. It is never stored; only the log is.
|
for one role, fitted to that model's window. It is never stored; only the log is.
|
||||||
Fitting, in order: shorten old tool results to their first and last lines; drop
|
Fitting, in order: shorten old tool results to their first and last lines; drop
|
||||||
the oldest events (with a note saying so); never drop the system prompt, the
|
the oldest events (with a note saying so); never drop the system prompt, the
|
||||||
approved plan or the most recent turns. A call that still doesn't fit is not sent;
|
current plan or the most recent turns. A call that still doesn't fit is not sent;
|
||||||
the caller treats it as a failure (L9).
|
the caller treats it as a failure (L9).
|
||||||
|
|
||||||
**2. The work-item transcript** — the canonical log (L7).
|
**2. The work-item transcript** — the canonical log (L7).
|
||||||
@@ -396,7 +430,7 @@ the caller treats it as a failure (L9).
|
|||||||
happened from these, not by inferring it.
|
happened from these, not by inferring it.
|
||||||
- **Each role gets its own view:**
|
- **Each role gets its own view:**
|
||||||
- the driver sees the conversation, the facts, and helpers' reports;
|
- the driver sees the conversation, the facts, and helpers' reports;
|
||||||
- a delegated helper sees its brief, the approved plan, the facts, its own work,
|
- a delegated helper sees its brief, the current plan, the facts, its own work,
|
||||||
and the driver's work in the same milestone as compact narration (each step
|
and the driver's work in the same milestone as compact narration (each step
|
||||||
and how it went);
|
and how it went);
|
||||||
- `ask_expert` is stateless: the expert sees only the question;
|
- `ask_expert` is stateless: the expert sees only the question;
|
||||||
@@ -737,44 +771,83 @@ Designs and builds software projects, producing reviewed changes in Gitea.
|
|||||||
|
|
||||||
### D1. How it works
|
### D1. How it works
|
||||||
|
|
||||||
A dev work item is a task on one repository: a feature, a fix, a new project.
|
A dev work item is a task on one repository: a bug, a feature, a new project.
|
||||||
Through conversation, the agent and the operator agree on an architecture (for a
|
Work arrives through Gitea issues or conversation, and leaves as reviewed PRs.
|
||||||
new project, or a significant change) and a build plan; the agent then works
|
|
||||||
through the plan's milestones, each producing a PR, and keeps the project's
|
|
||||||
documents up to date as it goes.
|
|
||||||
|
|
||||||
`use <project>` opens or resumes a work item on a repository. Messages sent before
|
**Intake: an issue assigned to `dev-agent`.** Assignment says whose job it is.
|
||||||
it are kept for it (L5).
|
- **The operator's issue becomes the work item's record;** the agent doesn't open a
|
||||||
|
second one. Only issues filed or assigned by allowlisted operators are acted on
|
||||||
|
(L11).
|
||||||
|
- **Unassigned issues are backlog,** never work. The agent can discuss them when
|
||||||
|
asked.
|
||||||
|
- **An issue with open Gitea dependencies is blocked** (L1) until they close.
|
||||||
|
- **On assignment the agent acknowledges** ("queued myproject#14, 1 ahead"), and the
|
||||||
|
item waits its turn (L1).
|
||||||
|
|
||||||
|
**Starting an item.** The agent reads the project's documents (D2), then
|
||||||
|
**restates its understanding** in the item's Matrix thread (L5): what it takes the
|
||||||
|
request to mean, how it fits the architecture, and its first step. Then:
|
||||||
|
- **An issue labelled `bug`** proceeds after a short grace period (as in L1), unless
|
||||||
|
something below says to talk first.
|
||||||
|
- **Anything else** (a feature, a change, a question) waits for the operator's
|
||||||
|
go-ahead after the restatement; the conversation is where the design is agreed.
|
||||||
|
- **Talk first when:** the issue is labelled `discuss`; the agent finds the report
|
||||||
|
unclear (it asks its questions instead of restating); or it can't reproduce a
|
||||||
|
bug. It never fixes a bug it couldn't see.
|
||||||
|
- **The agent never classifies an issue itself.** It may suggest ("this reads like
|
||||||
|
a bug; say *go* and I'll start"); labels and the operator decide. A missing label
|
||||||
|
costs at most a wait, never unwanted work.
|
||||||
|
|
||||||
|
**The flows.**
|
||||||
|
- **A bug:** reproduce (ideally as a failing test), fix, verify, and open a PR that
|
||||||
|
closes the issue.
|
||||||
|
- **A feature:** agree the design in conversation, write a build plan if the work
|
||||||
|
is longer than about one PR (D2), then work through it as milestones (D4).
|
||||||
|
- **A new project:** begins as a conversation, however vague. If it leads to a
|
||||||
|
project, the agent says what it needs provisioned: a repository, its protection
|
||||||
|
and the agent's access (D4), a build VM, and the project's configuration. The
|
||||||
|
operator provisions these (later `nisse-ops`, X4). The agent then opens a tracking
|
||||||
|
issue in the new repository ("implement the build plan"), and the architecture
|
||||||
|
lands in one or more PRs, followed by the build plan's milestones.
|
||||||
|
- **Progress** on a tracking issue is posted as it happens: facts by the harness
|
||||||
|
(milestone started, PR opened or merged), prose by the agent when there's
|
||||||
|
something worth saying.
|
||||||
|
|
||||||
|
**Finishing.** The final PR closes the issue on merge; the agent closes the work
|
||||||
|
item, after checking what is left open (D5).
|
||||||
|
|
||||||
### D2. Documents are the workflow
|
### D2. Documents are the workflow
|
||||||
|
|
||||||
The project's own documents carry the agreement between the operator and the
|
The project's own documents live in its repository and carry its design forward:
|
||||||
agent, and live in its repository:
|
|
||||||
|
|
||||||
- **`ARCHITECTURE.md`** — what the project is, how it fits together, and why. The
|
- **`ARCHITECTURE.md`** — what the project is, how it fits together, and why. The
|
||||||
durable "what and why". Created with a new project; changed whenever the design
|
durable "what and why". Created with a new project, and kept current by the agent:
|
||||||
changes.
|
a change to the design updates it.
|
||||||
- **Build plans** — how a piece of work gets done, as a sequence of milestones.
|
- **Build plans** — how a piece of work gets done, as a sequence of milestones,
|
||||||
Short-lived: one per body of work, kept in the repo for the record.
|
under `docs/plans/` or similar. The agent's working documents: how it stays
|
||||||
|
organised across context windows and sessions, and its own sanity check.
|
||||||
|
|
||||||
**Both are always discussed.** The agent drafts, the operator and agent talk it
|
**Neither is a gate.** They are reviewed the way all work is, in PRs.
|
||||||
through, and the document lands as a PR the operator approves. An approved
|
- **Architecture changes** go in the PR with the code when small; the agent may
|
||||||
architecture and build plan are the scope (L3) for everything that follows.
|
raise a larger one first. An issue labelled `design` asks for the design to be
|
||||||
|
agreed in conversation before any code. Without the label it is the agent's
|
||||||
|
judgement, and a wrong call costs a review, not safety.
|
||||||
|
- **Build plans are written for work longer than about one PR,** committed with the
|
||||||
|
work, so every PR shows the current plan and how it changed. The first PR of a
|
||||||
|
multi-milestone piece of work includes the whole plan, so a wrong direction shows
|
||||||
|
at the first review. The operator doesn't approve plans; the agent asks for
|
||||||
|
feedback when it wants it, and the operator can ask to discuss one at any time.
|
||||||
|
|
||||||
**A build plan specifies; it doesn't implement.** Each milestone states its goal,
|
**A build plan specifies; it doesn't implement.** Each milestone states its goal,
|
||||||
the interfaces and behaviour it adds or changes, edge cases, and **tests as
|
the interfaces and behaviour it adds or changes, edge cases, and **tests as
|
||||||
acceptance criteria**. It includes code only where the code *is* the clearest
|
acceptance criteria**. It includes code only where the code *is* the clearest
|
||||||
specification (a tricky algorithm, an exact format). It never manages branches
|
specification (a tricky algorithm, an exact format). It never manages branches
|
||||||
(D4). How much detail it needs is informed by the driver's capability profile
|
(D4). How much detail it needs is informed by the driver's capability profile
|
||||||
(L9).
|
(L9). It may note where the agent means to check in with the operator, and which
|
||||||
|
milestones aren't expected to change code.
|
||||||
|
|
||||||
**Each milestone is marked** pre-approved (proceed when reached) or needs discussion
|
**Progress is recorded in the plan itself:** the agent marks milestones done as
|
||||||
(stop and talk first), and says whether it is expected to change code (a review or
|
part of each PR. The framework never parses a plan (D4).
|
||||||
investigation milestone may not).
|
|
||||||
|
|
||||||
The Gitea issue for the work item carries the conversation's record: plans and
|
|
||||||
approvals are posted there as comments, so the agreement survives loss of the
|
|
||||||
agent's state (L8).
|
|
||||||
|
|
||||||
### D3. The workspace
|
### D3. The workspace
|
||||||
|
|
||||||
@@ -788,7 +861,7 @@ commands run.
|
|||||||
below). Work pushed to Gitea survives; a commit not yet pushed may be lost when a
|
below). Work pushed to Gitea survives; a commit not yet pushed may be lost when a
|
||||||
VM is wiped, and that is accepted.
|
VM is wiped, and that is accepted.
|
||||||
|
|
||||||
**A fresh, clean workspace at `use <project>`.**
|
**A fresh, clean workspace when a work item starts.**
|
||||||
- Fetch from the repository, and check out a clean tree at the latest base branch.
|
- Fetch from the repository, and check out a clean tree at the latest base branch.
|
||||||
- Anything left in a previous workspace (uncommitted changes, local branches,
|
- Anything left in a previous workspace (uncommitted changes, local branches,
|
||||||
unpushed commits) is **set aside**, never silently discarded or carried over,
|
unpushed commits) is **set aside**, never silently discarded or carried over,
|
||||||
@@ -818,9 +891,25 @@ a corrupt `.pyc`.
|
|||||||
|
|
||||||
### D4. Git, branches and PRs
|
### D4. Git, branches and PRs
|
||||||
|
|
||||||
- **The harness owns branches.** Each milestone works on a branch the harness
|
- **The harness owns branches.** Plans and models never create or switch
|
||||||
creates from the work item's current state; plans and models never create or
|
branches.
|
||||||
switch branches.
|
- **The workspace is never on the default branch:** when a work item starts, the
|
||||||
|
harness puts it on a branch of its own.
|
||||||
|
- **Milestones are started and finished by control tools** (L13):
|
||||||
|
`start_milestone(name)` makes the harness cut the milestone's branch;
|
||||||
|
`finish_milestone(summary)` makes it commit, push, open the PR and record the
|
||||||
|
fact. The model decides when, from its plan; the name is the model's, and the
|
||||||
|
harness doesn't check it against the plan.
|
||||||
|
- **Mistakes are made harmless,** not trusted away: finishing without a start
|
||||||
|
cuts the branch then; starting while another milestone is in progress is
|
||||||
|
refused; work done outside a milestone is still on a harness branch.
|
||||||
|
- **Wait for the merge between milestones.** The next milestone starts only after
|
||||||
|
the previous milestone's PR has merged, read from Gitea; until then the work item
|
||||||
|
waits on the operator and the agent works on something else (L1). Stacked PRs
|
||||||
|
are a possible later addition (Q).
|
||||||
|
- **Parking commits and pushes the item's branch,** so another work item on the
|
||||||
|
same project starts from a fresh checkout (D3) and the parked one resumes from
|
||||||
|
its branch.
|
||||||
- **Only the milestone's own changes are published:** what the agent changed,
|
- **Only the milestone's own changes are published:** what the agent changed,
|
||||||
never build artifacts (standard excludes in the clone, and committing only what
|
never build artifacts (standard excludes in the clone, and committing only what
|
||||||
the work produced). Anything left out is reported.
|
the work produced). Anything left out is reported.
|
||||||
@@ -835,10 +924,11 @@ a corrupt `.pyc`.
|
|||||||
- **Publishing is idempotent** (L8): an open PR for the branch is adopted and
|
- **Publishing is idempotent** (L8): an open PR for the branch is adopted and
|
||||||
updated, never duplicated.
|
updated, never duplicated.
|
||||||
- **A milestone that completes without changes is done, not failed,** when it
|
- **A milestone that completes without changes is done, not failed,** when it
|
||||||
wasn't expected to change code. The agent reports its result and moves on as the
|
wasn't expected to change code. The agent reports its result and moves on. An
|
||||||
build plan says. An unexpected "no changes" is raised with the operator.
|
unexpected "no changes" is raised with the operator.
|
||||||
- **Moving past a milestone checks its PR's state** in Gitea. If it is still open
|
- **The agent never owns or administers a repository.** Whoever creates a repo can
|
||||||
and unmerged, the agent says so and asks, rather than leaving it behind.
|
turn its protection off, so repositories are created and protected by the operator
|
||||||
|
(later `nisse-ops`), and `dev-agent` is a collaborator with write access.
|
||||||
- **The project's default branch is protected,** and this is verified, not
|
- **The project's default branch is protected,** and this is verified, not
|
||||||
assumed: the agent's own token must be refused when pushing to it, and when
|
assumed: the agent's own token must be refused when pushing to it, and when
|
||||||
merging without whatever approval the trust dial requires (L3). A test asserts
|
merging without whatever approval the trust dial requires (L3). A test asserts
|
||||||
@@ -853,8 +943,8 @@ a corrupt `.pyc`.
|
|||||||
- **Intake is exactly as in L8:** cursors, at-most-once taking, at-least-once
|
- **Intake is exactly as in L8:** cursors, at-most-once taking, at-least-once
|
||||||
answering, redelivery after a crash.
|
answering, redelivery after a crash.
|
||||||
- **Merging follows the trust dial** (L3). Today the operator merges. As confidence
|
- **Merging follows the trust dial** (L3). Today the operator merges. As confidence
|
||||||
grows, the dial may let the agent merge a pre-approved milestone once checks pass
|
grows, the dial may let the agent merge its own PRs once checks pass and the
|
||||||
and the required approvals are recorded; the branch protection must then require
|
required approvals are recorded; the branch protection must then require
|
||||||
an operator approval the agent's account can't satisfy, so the merge rule is
|
an operator approval the agent's account can't satisfy, so the merge rule is
|
||||||
enforced by Gitea, not by the agent.
|
enforced by Gitea, not by the agent.
|
||||||
- **Finishing a work item** closes its Gitea issue with a note (completed or
|
- **Finishing a work item** closes its Gitea issue with a note (completed or
|
||||||
@@ -868,8 +958,8 @@ a corrupt `.pyc`.
|
|||||||
| 2 (in scope) | Editing the workspace, committing to milestone branches, pushing them, opening and updating PRs, commenting on its issues and PRs, cleaning caches, installing project dependencies, packages and toolchains on the project's build VM |
|
| 2 (in scope) | Editing the workspace, committing to milestone branches, pushing them, opening and updating PRs, commenting on its issues and PRs, cleaning caches, installing project dependencies, packages and toolchains on the project's build VM |
|
||||||
| 3 | Merging to the default branch (unless the trust dial allows), deleting remote branches or others' work, changing repository settings, anything outside the work item's repo or its project's build VM |
|
| 3 | Merging to the default branch (unless the trust dial allows), deleting remote branches or others' work, changing repository settings, anything outside the work item's repo or its project's build VM |
|
||||||
|
|
||||||
Its scope sources are the approved architecture, the build plan and each
|
Its scope source is the assigned issue and what was agreed in its conversation
|
||||||
milestone's marking.
|
(L3); `ARCHITECTURE.md` and the build plan inform it but don't widen it.
|
||||||
|
|
||||||
### D7. Deployment and isolation
|
### D7. Deployment and isolation
|
||||||
|
|
||||||
@@ -919,7 +1009,7 @@ they take effect.
|
|||||||
| Axis | `nisse-dev` | `nisse-ops` |
|
| Axis | `nisse-dev` | `nisse-ops` |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Undo | discard a branch, revert a snapshot | often none (`zfs destroy`, a firewall lockout) |
|
| Undo | discard a branch, revert a snapshot | often none (`zfs destroy`, a firewall lockout) |
|
||||||
| Scope source | architecture and build plan | approved step sequences (O2) |
|
| Scope source | the assigned issue and its conversation | approved step sequences (O2) |
|
||||||
| Default for class 3 | discuss | discuss, and exact-step approval |
|
| Default for class 3 | discuss | discuss, and exact-step approval |
|
||||||
| Work shape | milestones → PRs | short reactive tasks and scheduled checks → live changes |
|
| Work shape | milestones → PRs | short reactive tasks and scheduled checks → live changes |
|
||||||
| Driver of work | the operator in Matrix, Gitea | Vikunja tickets, alerts, duties, the operator |
|
| Driver of work | the operator in Matrix, Gitea | Vikunja tickets, alerts, duties, the operator |
|
||||||
@@ -1083,10 +1173,11 @@ identity, 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 (llama-
|
||||||
(llama-swap on an RTX 4090 host), Vikunja, Vaultwarden, LLDAP with Authelia, and
|
swap on an RTX 4090 host), Vikunja, Vaultwarden, LLDAP with Authelia, and Syncthing
|
||||||
Syncthing for the operator's copy of the knowledge vault (L10). Each agent gets its own account, scoped token and room in each service
|
for the operator's copy of the knowledge vault (L10). Each agent gets its own
|
||||||
it uses; nothing is shared between agents.
|
account, scoped token and room in each service it uses; nothing is shared between
|
||||||
|
agents.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -1120,6 +1211,9 @@ it uses; nothing is shared between agents.
|
|||||||
- **How `nisse-ops`' MCP servers reach the second site** from the agent host
|
- **How `nisse-ops`' MCP servers reach the second site** from the agent host
|
||||||
(Tailscale on the host, with other agents' networks denied the tailnet, or a
|
(Tailscale on the host, with other agents' networks denied the tailnet, or a
|
||||||
subnet route), since Tailscale on the host serves every container on it.
|
subnet route), since Tailscale on the host serves every container on it.
|
||||||
|
- **Stacked PRs.** Starting the next milestone before the previous PR merges,
|
||||||
|
with the harness rebasing and retargeting. Considered after experience with
|
||||||
|
waiting for merges (D4).
|
||||||
- **How long idle before a build VM is collected,** and whether collection needs the
|
- **How long idle before a build VM is collected,** and whether collection needs the
|
||||||
operator's word.
|
operator's word.
|
||||||
|
|
||||||
@@ -1135,15 +1229,17 @@ history):
|
|||||||
rigid state machine gating every phase.
|
rigid state machine gating every phase.
|
||||||
- **The agent loop (L2)** replaces the per-agent state machines (old A4, B1). What
|
- **The agent loop (L2)** replaces the per-agent state machines (old A4, B1). What
|
||||||
stays fixed is only what authority and durability need.
|
stays fixed is only what authority and durability need.
|
||||||
- **Approvals as scoped permissions (L3),** with pre-approved and needs-discussion
|
- **Approvals as scoped permissions (L3),** with scope from the assigned issue and
|
||||||
milestones and an operator-set trust dial. Revision binding is kept and extended
|
its conversation, labels to steer, and an operator-set trust dial. Revision
|
||||||
(task-wide revisions, stamping on arrival).
|
binding is kept and extended (task-wide revisions, stamping on arrival).
|
||||||
- **The local model drives everything (P7, L9);** frontier models are helpers. The
|
- **The local model drives everything (P7, L9);** frontier models are helpers. The
|
||||||
old "planning always escalates" phase policy is dropped.
|
old "planning always escalates" phase policy is dropped.
|
||||||
- **Context and memory (L6)** is new: transcript scoping, attribution, orchestrator
|
- **Context and memory (L6)** is new: transcript scoping, attribution, orchestrator
|
||||||
facts, scope memory, agent memory, and how memory is written and used.
|
facts, scope memory, agent memory, and how memory is written and used.
|
||||||
- **Documents as the dev workflow (D2),** a fresh workspace per task and toolchain
|
- **The dev workflow (D1, D2):** issues assigned to the agent as intake, labels to
|
||||||
preflight (D3), and git hygiene learned from the live runs (D4).
|
steer, documents kept current through PRs, and build plans as the agent's working
|
||||||
|
documents rather than gates; a fresh workspace per task and toolchain preflight
|
||||||
|
(D3), and git hygiene learned from the live runs (D4).
|
||||||
- **Conversation (L5)** is a first-class requirement, not a command interpreter.
|
- **Conversation (L5)** is a first-class requirement, not a command interpreter.
|
||||||
- **The knowledge vault (L10)** replaces Outline: Markdown on the agent host, shared
|
- **The knowledge vault (L10)** replaces Outline: Markdown on the agent host, shared
|
||||||
between agents by mounts, synced to the operator by Syncthing. Revised in PR #90.
|
between agents by mounts, synced to the operator by Syncthing. Revised in PR #90.
|
||||||
|
|||||||
Reference in new issue
Block a user