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.
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.
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 |
|---|---|---|
| opencode2 | opencode2 acp | Seeded as the default when installed. This is the one I use. |
| opencode | opencode acp | Fallback when opencode2 is not installed. |
| pi | pi-acp | Also 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 |
|---|---|
| Task | The unit of work. Carries status, priority, tags, a deadline, a summary, and next steps. |
| Item | Something external: a Slack thread, GitHub issue or PR, Drive doc, URL, note, commit, or file. De-duplicated by URL or external id. |
| Association | A link between an item and a task, with an optional note explaining why it is attached. |
| Repository | A local git checkout registered by path. |
| Repository group | A named set of repositories a task's agent should consider. Set with --group-id. |
| Worktree | An isolated git worktree created for a task from a registered repository. |
| Agent run | One prompt sent to a harness in a working directory. Its transcript is a stream of events. |
| Agent session | A session recorded by hand, for one Agentic did not start, such as an openchamber session. |
| Context refresh | A special agent run that reads the task and its items and rewrites the summary and next steps. |
| Change | A unit of factory output recorded against a task and moved through a lifecycle. |
| Stack entry | A task's place on the focus stack: position, whether it is current, and a soft-delete timestamp. |
| Task session | A stretch of time a stack entry spent as the current task. |
| Scheduled task | A shell command the app runs on a cron schedule, with run history. |
| Operation | An audit record of a mutating request: method, path, status, client, and human or agent. |
| Person | Someone 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
- File a task, often from a GitHub issue or a Slack thread.
- Attach evidence: the Slack thread, the PR, the doc, the note.
- Register a repository and create a worktree for the task.
- Start an agent run in that worktree with a prompt.
- Watch the run, then mark the task
in_progress. - When the work lands, record a change, move it through verified, accepted.
- Refresh context so the summary and next steps reflect reality.
- Pop the task from the focus stack, which marks it done.
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.
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
- Open the Agentic web UI and check the focus stack to see the current task.
- Read the current task's summary and next steps in the web UI.
- Open the linked openchamber session, or start a new run in the task's worktree.
During the day
- Work inside the task's worktree. Agent runs and edits stay scoped there.
- 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.
- When blocked on someone, park the task from the web UI.
- When a task is done, record a change and move it through verified, accepted.
End of day
- Refresh context for any task I touched.
- Pop finished tasks from the focus stack.
- 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.
- Run the
create-issueskill to draft the issue with background, acceptance criteria, and a time budget. - Create the GitHub issue (via
ghorghx). - File the task in Agentic from the issue URL:
agentic task create --github-url <issue url>. - 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.--tagsand--repository-idsare repeatable; pass--empty-tagsor--empty-repository-idsto clear them.createtakes--group-idand--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 addso 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.
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.mdbesideAGENTS.md, for cross-project lessons: workflow preferences, tooling gotchas, process decisions. - A project-level
MEMORY.mdin 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.
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 showreports each metric's direction:improving,worsening,flat,no-baseline, orno-data.metrics cycle-timereads 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.
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 |
|---|---|
| slack | agentic item create --url <slack thread url>, or task create --slack-url. |
| github | agentic item create --url <issue or PR url>, or task create --github-url. |
| gdrive | Linked as a URL; refreshed by the background job. |
| url | Any web page. |
| note | agentic item create --content "Remember to rotate the token". |
| commit | A commit reference. |
| file | agentic 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 |
|---|---|---|---|
| agentic | TomzxCode mine | The task tracker CLI. Tasks, items, links, worktrees, runs, sessions, context, metrics. | The whole methodology |
| opencode2 | anomalyco | The coding agent harness, reached over ACP. Default harness when installed. | openchamber, agent runs |
| openchamber | openchamber | Web UI for sessions, files, and diffs. | Daily coding |
| VS Code | microsoft | Text editor, used from time to time when openchamber's built-in editor is not enough. | Editing |
| ghx | TomzxCode mine | Extended 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 |
| gh | cli | GitHub CLI. Used where ghx does not cover the operation (repo search, merge, PR creation). | Agentic, git workflows |
| slackx | TomzxCode mine | Slack cache and reader: threads, channel history, DMs, users, channels, with a local SQLite store. | Agentic (Slack items), Slack skills |
| git | git-scm | Version control, worktrees, branches. | Worktrees, commits |
| uv | astral-sh | Python package manager and runner. | Agentic server, scripts |
| jq | jqlang | JSON filtering for piped CLI output. | Scripting |
| asciinema | asciinema | Terminal demo recording, rendered to GIF or SVG. | verify-pr, validate-implementation |
| playwright | microsoft | Web UI recording and screenshots. | verify-pr, validate-implementation |
| ruff | astral-sh | Python linter and formatter. | Python projects |
| pytest | pytest-dev | Python test runner. | Python projects |
How the tools fit together
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]
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 tasks | agentic task list |
| Current task | agentic stack current |
| Show the stack | agentic stack list |
| Task details | agentic task get <task> |
| Task timeline | agentic task timeline <task> |
| Context | agentic context get <task> |
| Refresh context | agentic context refresh <task> |
| Start a run | agentic run create <task> --prompt "..." |
| Wait for a run | agentic run wait <run-id> |
| Stream a run | agentic run stream <run-id> |
| Create a worktree | agentic worktree create <task> --branch fix/x |
| Record a session | agentic session add <task> <session-id> --label openchamber |
| Pop the current task | agentic stack pop |
| Metrics | agentic metrics show |
| Cycle time | agentic 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.