Agentic Development Methodology

This page describes how I build software today. The coding environment is openchamber running opencode2. The work tracker is Agentic, a local-first app I develop, which ties together the Slack threads, GitHub issues and pull requests, Drive docs, URLs, and notes that feed a unit of work.

The core idea: one task at a time, an isolated worktree per task, an agent that can pick up where I left off because the task carries its own summary and next steps, and a small set of metrics that tell me whether the factory is getting more autonomous over time.

openchamber opencode2 Agentic focus stack worktrees agent runs context refresh autonomy rate DeepSeek v4.1 Flash 1017

At a glance

Where I work

openchamber is the web UI. opencode2 is the coding agent behind it. I keep one session per task and record the session id in Agentic so I can reopen it later.

What I track

Agentic holds tasks. Each task links to items: Slack threads, GitHub issues and PRs, Drive docs, URLs, notes, files. The task also carries a summary and next steps that an agent maintains.

How I focus

The focus stack puts one task on top. Everything else queues below. I pop the current task when it is done and the next one promotes automatically.

How I isolate work

Each task gets its own git worktree from a registered repository. Agent runs and edits happen inside that worktree, so tasks never step on each other.

How I resume

Task context (summary plus next steps) is rewritten by a context refresh run. When I return to a task, the agent reads it and continues without me re-explaining.

How I measure

Every piece of work that reaches production becomes a change. I track whether it needed human intervention (autonomy rate) and whether it survived (yield).

Main model

I rely mostly on DeepSeek v4.1 Flash 1017 as my main model, used through opencode2 in openchamber.

Environment: openchamber + opencode2

openchamber is the web interface I use to talk to the agent. opencode2 is the coding agent itself, reached over ACP. Together they replace the terminal-only loop: I can open a session, attach files and images, and let the agent edit and run commands while I watch.

Why this pair

  • openchamber keeps sessions, files, and diffs in one place, so switching tasks is a tab change instead of a context switch in my head.
  • opencode2 is the default harness Agentic seeds when it is installed. If it is missing, Agentic falls back to opencode, then to pi.
  • Sessions opened in openchamber can be recorded in Agentic as agent sessions, with their session id, harness, working directory, and label, so the links that reopen them are one click away.

Main model

I rely mostly on DeepSeek v4.1 Flash 1017 as my main model, run through opencode2 inside openchamber. It is the default I reach for when starting a run or a context refresh.

Text editor

I also use VS Code as a text editor from time to time, because openchamber's built-in text editor is meh. openchamber stays the main surface for sessions, files, and diffs; VS Code is a fallback for editing.

Settings that connect the two

Agentic stores three settings that make openchamber reachable from a task. I set them once.

agentic settings set --openchamber-url http://box:3001
agentic settings set --openchamber-session-path "/?session={session}"
agentic settings set --terminal-url-template "https://terminal.example/?cwd={cwd}"

With these set, agentic session get and agentic run get print the links that reopen a session in openchamber or a terminal.

The Agentic API has no authentication. I expose it only on a trusted network. The CLI talks to it at http://127.0.0.1:8600 by default.

Harnesses

A harness is a coding-agent process reachable over ACP. Agentic does not care which agent I use; it just needs a command on PATH.

Harness Command Notes
opencode2opencode2 acpSeeded as the default when installed. This is the one I use.
opencodeopencode acpFallback when opencode2 is not installed.
pipi-acpAlso seeded. Useful for comparison runs.

I can register a custom harness with a resume command template, so Agentic knows how to reopen a session for it.

agentic harness create myagent opencode --args acp --model gpt-x --resume-command "opencode --session {session}"

harness list marks each harness available or missing by looking its command up on PATH.

Core concepts

Everything in Agentic hangs off a task. These are the pieces.

Concept What it is
TaskThe unit of work. Carries status, priority, tags, a deadline, a summary, and next steps.
ItemSomething external: a Slack thread, GitHub issue or PR, Drive doc, URL, note, commit, or file. De-duplicated by URL or external id.
AssociationA link between an item and a task, with an optional note explaining why it is attached.
RepositoryA local git checkout registered by path.
Repository groupA named set of repositories a task's agent should consider. Set with --group-id.
WorktreeAn isolated git worktree created for a task from a registered repository.
Agent runOne prompt sent to a harness in a working directory. Its transcript is a stream of events.
Agent sessionA session recorded by hand, for one Agentic did not start, such as an openchamber session.
Context refreshA special agent run that reads the task and its items and rewrites the summary and next steps.
ChangeA unit of factory output recorded against a task and moved through a lifecycle.
Stack entryA task's place on the focus stack: position, whether it is current, and a soft-delete timestamp.
Task sessionA stretch of time a stack entry spent as the current task.
Scheduled taskA shell command the app runs on a cron schedule, with run history.
OperationAn audit record of a mutating request: method, path, status, client, and human or agent.
PersonSomeone linked to tasks and items, so a task shows who it is for or about.

Every meaningful change writes a timeline event, so agentic task timeline <task> shows how a task evolved.

Task flow

A task moves through a simple lifecycle. Statuses are open, in_progress, blocked, done, and archived. Priorities are 0 low, 1 medium, 2 high (default), 3 urgent.

The common path

  1. File a task, often from a GitHub issue or a Slack thread.
  2. Attach evidence: the Slack thread, the PR, the doc, the note.
  3. Register a repository and create a worktree for the task.
  4. Start an agent run in that worktree with a prompt.
  5. Watch the run, then mark the task in_progress.
  6. When the work lands, record a change, move it through verified, accepted.
  7. Refresh context so the summary and next steps reflect reality.
  8. Pop the task from the focus stack, which marks it done.
Agent runs and context refreshes start a coding agent that can edit files and run commands, and permissions are auto-approved by default. I state the prompt and the working directory before starting one.

Focus stack

The focus stack is the current task plus the queue below it. I work one thing at a time. The app materializes the stack from in-flight tasks: every task that is open, in progress, or blocked and has never been on the stack joins at the bottom automatically.

agentic stack list                 # the stack, current task first
agentic stack current              # the current task (the top)
agentic stack history              # soft-deleted entries, most recent first

agentic stack push --title "Fix the flaky test"          # add a new task on top
agentic stack push --task-id <task> --position next      # add an existing task after the current one
agentic stack push --task-id <task> --position last      # add it at the bottom

agentic stack pop                  # mark the current task done and promote the next one
agentic stack promote <entry>      # move an entry to the top (make it current)
agentic stack reorder <entry> 2    # move an entry to position 2 (0 is current)
agentic stack edit <entry> --title "Better title" --description "..."
agentic stack remove <entry>       # soft delete the entry; the task is kept

--position is top (becomes current), next (after the current task), or last (the bottom). pop marks the task done. remove only takes it off the stack and leaves the task as it was. A popped or removed task keeps its soft-deleted entry, so it is not re-added automatically; push it again to bring it back.

Each entry's text line shows its execution count and total time as the current task, so I can see where my attention went.

Worktrees and runs

Repositories and worktrees

I register a repository once, then create a worktree per task. This keeps tasks isolated on disk.

agentic repository list
agentic repository add /home/me/src/myrepo
agentic repository add /home/me/src/myrepo --name myrepo
agentic repository remove <repository>

agentic worktree list <task>
agentic worktree create <task>                                  # defaults to one of the task's repositories
agentic worktree create <task> --repository-id <repository> --branch fix/ingest --base main
agentic worktree remove <task> <worktree>
worktree remove runs git worktree remove --force and prunes. Any uncommitted changes in that worktree are lost. I confirm before running it.

Agent runs

An agent run is one prompt sent to a harness in a working directory. Its transcript is a stream of events.

agentic run create <task> --prompt "Investigate the failing test"
agentic run create <task> --worktree-id <worktree> --prompt "Implement the fix"
agentic run create <task> --cwd /home/me/src/myrepo --harness-id opencode --prompt "Summarize the repo"

agentic run list <task>
agentic run get <run-id>          # includes session_id, cwd, and session links
agentic run events <run-id>       # full transcript
agentic run stream <run-id>       # live: JSON lines when piped, text on a TTY
agentic run wait <run-id>         # polls every --interval (default 2s) up to --timeout (default 600s)
agentic run cancel <run-id>

Run statuses: queued, running, succeeded, failed, cancelled. Run kinds: chat (a normal prompt) and refresh_context (started by context refresh).

run create picks the working directory in this order: --cwd, then --worktree-id, then a default worktree or the task's first repository. Leave --harness-id unset to use the task's harness, then the app default. --model overrides the harness's model for that run only.

A run records the session it produced, so run get shows the links that reopen it.

Sessions

A session records an agent session against a task by hand, for one Agentic did not start, such as an openchamber session. run get and session get both expose the links that reopen a session: openchamber, a terminal template, and the harness's resume command.

I can also start agent sessions directly from Agentic (via run create). Agentic picks the working directory, launches the harness, and records the session id and reopen links automatically.

agentic session list <task>
agentic session add <task> <agent-session-id> --harness-id opencode --cwd /home/me/src/myrepo --label "investigation"
agentic session get <task> <record-id>
agentic session update <task> <record-id> --label "renamed"
agentic session remove <task> <record-id>

Mind the two ids: session add takes the agent's session id (the one the harness reports), while get, update, and remove take the recorded session's id (the first column of session list). session add defaults the harness to the task's harness.

This is the bridge between openchamber and Agentic. When I open a session in openchamber for a task, I record its id with session add so the task keeps a reopen link.

Task context

The summary and next steps are agent-maintained and make resuming a task quick. This is the part that makes the methodology work across days: I do not re-explain the task to the agent each morning.

agentic context get <task>        # current summary and next steps
agentic context refresh <task>    # starts a refresh_context run that rewrites them

context refresh returns a run; watch it with run wait or run stream. The run reads the task and its items and rewrites the summary and next steps.

I can also hand-write a summary when I want to pin something the agent should not overwrite lightly.

agentic task update <task> --summary "hand-written summary"

A typical day

In a typical day I work through the Agentic web UI, not the CLI. The web UI shows the focus stack, the current task's summary and next steps, its linked items, and the runs and sessions attached to it. The CLI commands below are there when I need them, but the web UI is the primary surface.

Morning

  1. Open the Agentic web UI and check the focus stack to see the current task.
  2. Read the current task's summary and next steps in the web UI.
  3. Open the linked openchamber session, or start a new run in the task's worktree.

During the day

  1. Work inside the task's worktree. Agent runs and edits stay scoped there.
  2. When a new thread or issue appears, file a task or attach it as an item from the web UI, instead of losing it in a tab.
  3. When blocked on someone, park the task from the web UI.
  4. When a task is done, record a change and move it through verified, accepted.

End of day

  1. Refresh context for any task I touched.
  2. Pop finished tasks from the focus stack.
  3. Run the end-of-day review skill to summarize GitHub and Slack activity.

Filing a task

My default path is the create-issue skill to write the GitHub issue, then I provide context in a new session. The issue becomes the task's anchor, and the new session is where I (or an agent) pick it up.

  1. Run the create-issue skill to draft the issue with background, acceptance criteria, and a time budget.
  2. Create the GitHub issue (via gh or ghx).
  3. File the task in Agentic from the issue URL: agentic task create --github-url <issue url>.
  4. Open a new session (in openchamber or as an agent run) and provide the issue context so work can start.

Other entry points

  • From a Slack thread: agentic task create --slack-url <thread url>. This fetches the thread, links it, and starts an agent run that names the task and summarizes the discussion.
  • By hand: agentic task create --title "..." --priority 3 --tags bug --tags ci. --tags and --repository-ids are repeatable; pass --empty-tags or --empty-repository-ids to clear them. create takes --group-id and --harness-id.
  • Parked work: agentic task create --title "Renew TLS cert" --snooze 2026-11-01.

Starting work

Attach evidence

agentic link add <task> --item-id <item>
agentic link add <task> --url https://github.com/o/r/issues/482 --note "the repro"
agentic link add <task> --content "scratch note"
agentic link remove <task> <item>

link add with no --item-id creates a new item from --url, --path, --content, or --title, then associates it. Use --note to record why the item is attached.

Create the worktree and run

agentic repository add /home/me/src/myrepo
agentic worktree create <task> --branch fix/482
agentic run create <task> --worktree-id <worktree> --prompt "Fix issue 482 and run the tests"
agentic run wait <run-id>
agentic task update <task> --status in_progress

Record a session opened elsewhere

agentic session add <task> <agent-session-id> --cwd /home/me/src/myrepo --label "openchamber"

Doing work

Once a task is filed and a worktree exists, the actual work happens inside that worktree. Agent runs and edits stay scoped there, so tasks never step on each other.

  • Work inside the task's worktree. Code changes, tests, and commits belong to that worktree.
  • Start an agent run with a prompt: agentic run create <task> --worktree-id <worktree> --prompt "...".
  • Or start a run directly from Agentic, which picks the working directory and records the session and reopen links.
  • Open an openchamber session for hands-on editing when the agent's run is not enough.
  • Record a session opened elsewhere with agentic session add so the task keeps a reopen link.
  • When a new thread or issue appears mid-work, file a task or attach it as an item instead of losing it in a tab.
  • When blocked on someone, park the task: agentic task update <task> --waiting-on <person> --follow-up 2026-11-05.
Work stays scoped to the worktree. The agent's permissions are auto-approved by default, so I state the prompt and working directory before starting a run.

Ending work

Refresh context

agentic context refresh <task>
agentic run wait <run-id>

Record a change

A change is the unit of factory output the metrics are computed from. I record one per piece of work that reaches production.

agentic change create <task> --title "Fix flaky ingest test"
agentic change create <task> --title "Add retry" --change-class bugfix --external-ref <sha>
agentic change create <task> --title "Add retry" --repository-id <repository> --worktree-id <worktree>

agentic change verify <change>    # verified
agentic change accept <change>    # reached production
agentic change reject <change>    # rejected before acceptance
agentic change revert <change>    # an accepted change that did not survive

Change classes: feature, bugfix, refactor, chore, docs, test, trivial. Statuses: proposed, verified, accepted, rejected, reverted. change create starts proposed.

Interventions

agentic change intervene <change> --kind correction --note "fixed the migration by hand"

--kind is one of question, correction, manual_fix, rerun, approval, other. Any intervention, including an approval, marks the change non-touchless, which lowers the autonomy rate.

Pop the task

agentic stack pop    # marks the current task done and promotes the next one

Memory strategy

Memory is file-based and split into two layers: a short, durable layer that every session reads at startup, and a deeper PARA layer that compounds over time. The goal is to remember conclusions and preferences, not session narration.

Two memory files, read every session

  • A global MEMORY.md beside AGENTS.md, for cross-project lessons: workflow preferences, tooling gotchas, process decisions.
  • A project-level MEMORY.md in the repository root, for facts about that repository: conventions, decisions, gotchas.
  • Both are read at the start of each session, before any work.

What gets written

  • Conclusions, not session narration: decisions, conventions, gotchas, preferences.
  • Only what a future session cannot cheaply rediscover from the code, help output, or docs.
  • Never transient state that a near-term commit would invalidate: failing tests, in-flight refactors, known gaps.
  • Entries are concise, dated, and free of secrets and session-specific noise.

Slack knowledge base

Slack channels are ingested into temporal monthly memory files and then merged into theme-organized knowledge bases, so decisions made in threads survive and stay searchable.

Memory is written through skills, not by hand, so the format stays consistent and the durable layer stays short.

Changes and metrics

The metrics read the change records. They answer one question: is the factory getting more autonomous over time, and is the work surviving.

agentic metrics show                         # autonomy rate and yield vs their baselines
agentic metrics show --window-days 30 --observation-days 14 --tolerance 0.02
agentic metrics show --task-id <task> --change-class bugfix

agentic metrics cycle-time                    # issue close, review wait, and review-to-merge trends per repository
agentic metrics cycle-time --days 30 --bucket-days 7 --refresh
agentic metrics cycle-time --repository <repository>

agentic metrics baseline list
agentic metrics baseline set autonomy_rate 0.2 --note "before the factory run"
agentic metrics baseline set yield 0.8
agentic metrics baseline delete autonomy_rate
  • Autonomy rate is the share of accepted changes that needed no human intervention.
  • Yield is the share of accepted changes that survived the observation window without being reverted.
  • metrics show reports each metric's direction: improving, worsening, flat, no-baseline, or no-data.
  • metrics cycle-time reads each repository's GitHub activity and reports issue-close, review-wait, and review-to-merge trends. It makes one request per repository with a GitHub remote.

Autonomy rate and yield

Autonomy rate

Did the agent ship it without me? Any intervention marks the change non-touchless. The goal is for this to climb as the harness, prompts, and context improve.

Yield

Did it survive? A reverted change counts against yield. This catches changes that looked fine but broke something later.

I set a baseline before a big change to the factory, then compare. agentic metrics baseline set autonomy_rate 0.2 --note "before the factory run".

Integrations

Agentic's items cover the sources that feed work. The source is inferred from --url, --path, or --content; pass --source to override, and --external-id to set the upstream id used for de-duplication.

Source How it enters
slackagentic item create --url <slack thread url>, or task create --slack-url.
githubagentic item create --url <issue or PR url>, or task create --github-url.
gdriveLinked as a URL; refreshed by the background job.
urlAny web page.
noteagentic item create --content "Remember to rotate the token".
commitA commit reference.
fileagentic item create --path /home/me/src/myrepo/notes.md.

Refresh policy

The background refresh job re-fetches Slack and GitHub items on a per-age schedule. I can tune it.

agentic settings set --slack-refresh-policy "1d=1h,7d=6h,30d=1d,*=7d"
agentic settings set --github-refresh-policy "1d=1h,7d=6h"

agentic item refresh <item>            # re-fetch metadata and content
agentic item refresh-due               # re-fetch the items the policy says are due
agentic item refresh-source slack      # re-fetch every item of one source now

ghx and slackx

Agentic runs ghx and slackx under the hood to fetch GitHub and Slack data. I can run them as CLI binaries or as RPC servers.

agentic settings set --ghx-backend rpc --ghx-rpc-url http://box:8010
agentic settings set --ghx-backend cli
agentic settings set --slackx-backend rpc --slackx-rpc-url http://box:8011 --slackx-rpc-token secret

Slack conversations can be marked done so later replies are flagged rather than silently reopening the thread.

agentic item done <item>
agentic item reopen <item>

People

I link people to tasks and items so a task shows who it is for or about. Useful for follow-ups and waiting states.

agentic person list
agentic person get <person>

agentic person create --name "Alice Smith" --aliases alice --aliases alice@example.com
agentic person update <person> --notes "owns ingest"
agentic person update <person> --aliases alice   # replaces the whole alias list
agentic person merge <person> --into <person>
agentic person delete <person>

agentic person link <person> --task <task>
agentic person link <person> --item <item>
agentic person link <person> --requested-by <task>
agentic person unlink <person> --task <task>

person link and unlink take exactly one of --task, --item, or --requested-by. merge folds one person into another, moving their aliases and links.

Scheduled tasks

A scheduled task runs a shell command on a cron schedule inside the app, separate from agent runs. Each keeps its run history. I use these for recurring checks.

agentic schedule list
agentic schedule get <schedule>
agentic schedule runs
agentic schedule runs --schedule-id <schedule> --limit 50

agentic schedule create "nightly" "npm test" "0 3 * * *"
agentic schedule create "digest" "uv run digest" "0 9 * * 1-5" --cwd /home/me/src/repo --timezone Europe/Paris
agentic schedule create "paused" "make audit" "0 0 1 * *" --disabled

agentic schedule update <schedule> --schedule "30 4 * * *"
agentic schedule update <schedule> --disable
agentic schedule update <schedule> --enable

agentic schedule run <schedule>
agentic schedule delete <schedule>

create takes NAME, COMMAND, and a 5-field cron SCHEDULE. --cwd defaults to the server's directory and --timezone to the server's zone. --disabled creates the task paused.

Operations log

Every mutating API request is recorded with the client that sent it and whether a human or an agent was behind it. This is the cross-cutting view of how work entered the system, including operations with no task to hang a timeline event off, such as settings, repositories, harnesses, and people.

agentic operation list                       # newest first, up to 100 by default
agentic operation list --client cli --actor agent
agentic operation list --limit 500

--client is web, cli, or api. --actor is human or agent. I set AGENTIC_ACTOR=agent so the server records my agent's mutations as agent-performed in the timeline and the operations log.

Tools relied on

The methodology leans on a small set of CLIs and services. Agentic calls several of them under the hood; I also run them directly.

Tool Owner Role Used by
agenticTomzxCode mineThe task tracker CLI. Tasks, items, links, worktrees, runs, sessions, context, metrics.The whole methodology
opencode2anomalycoThe coding agent harness, reached over ACP. Default harness when installed.openchamber, agent runs
openchamberopenchamberWeb UI for sessions, files, and diffs.Daily coding
VS CodemicrosoftText editor, used from time to time when openchamber's built-in editor is not enough.Editing
ghxTomzxCode mineExtended GitHub CLI: cached issue and PR browsing, inline review comments, line-range comments, thread replies, pending reviews, comment stash, edit and delete.Agentic (issue import), review skills
ghcliGitHub CLI. Used where ghx does not cover the operation (repo search, merge, PR creation).Agentic, git workflows
slackxTomzxCode mineSlack cache and reader: threads, channel history, DMs, users, channels, with a local SQLite store.Agentic (Slack items), Slack skills
gitgit-scmVersion control, worktrees, branches.Worktrees, commits
uvastral-shPython package manager and runner.Agentic server, scripts
jqjqlangJSON filtering for piped CLI output.Scripting
asciinemaasciinemaTerminal demo recording, rendered to GIF or SVG.verify-pr, validate-implementation
playwrightmicrosoftWeb UI recording and screenshots.verify-pr, validate-implementation
ruffastral-shPython linter and formatter.Python projects
pytestpytest-devPython test runner.Python projects

How the tools fit together

flowchart LR ME[Me
human] --> OC[openchamber
web UI] ME --> A[agentic
task tracker] OC --> OC2[opencode2
coding agent] OC2 --> WT[git worktree
per task] A --> OC2 A --> GHX[ghx
GitHub data] A --> SLX[slackx
Slack data] A --> GIT[git] A --> UV[uv] GHX -.fallback.-> GH[gh] WT --> CODE[edited code] CODE --> PR[PR via gh/ghx] OC2 --> REC[asciinema / playwright
recordings]
Prefer ghx over gh for listing, searching, and viewing issues and PRs, and for getting and posting comments. Fall back to gh only when ghx does not support the needed operation.

Command cheat sheet

Goal Command
List tasksagentic task list
Current taskagentic stack current
Show the stackagentic stack list
Task detailsagentic task get <task>
Task timelineagentic task timeline <task>
Contextagentic context get <task>
Refresh contextagentic context refresh <task>
Start a runagentic run create <task> --prompt "..."
Wait for a runagentic run wait <run-id>
Stream a runagentic run stream <run-id>
Create a worktreeagentic worktree create <task> --branch fix/x
Record a sessionagentic session add <task> <session-id> --label openchamber
Pop the current taskagentic stack pop
Metricsagentic metrics show
Cycle timeagentic metrics cycle-time

The CLI emits JSON when piped, so agentic task list | jq works without a flag. Pass --format text for the human-readable form even when piped. Global options: --api-url, --format, --timeout.