13 KiB
Superseded plan: retire oibot-agent from the Tobserver change workflow
Status
Superseded on 2026-07-29 by the normal-clone workflow. Dotfiles no longer load
tobserver-change or package tobserver-agent; repository-owned instructions
and checks should govern future Tobserver work. The remaining document is kept
only as historical migration context and must not be followed as an active plan.
Before removing any legacy credentials or workspace, resolve the preserved workspace recorded below explicitly.
- The standalone catalog skill is implemented on
agent/tobserver-personal-agitat commitce0f775and published as oibot/agent-skills PR #1. - AGit creation and a second linear push were verified against the same pull request without a write API token.
- Dotfiles are prepared to pin that catalog revision, load
create-skillandtobserver-changein Pi, and package the bundled helper astobserver-agent; Nix evaluation and the Home Manager build pass. ~/.ssh/confignow selects~/.ssh/id_ed25519withIdentitiesOnly yesfor normal Codeberg access and no longer auto-adds the bot key. Both aliases authenticate as their intended accounts.- The new Nix configuration has not been activated, the Agent Skills PR has not been merged, the bot alias remains available for the active legacy workspace, and no bot credential has been revoked or deleted.
- Cutover is blocked until the user confirms Tobserver
mainprotection in Codeberg and resolves or deliberately migrates the active legacy workspace at/private/var/folders/5p/sj0yx8w92b51dzngrxn9gqz00000gn/T/tobserver-agent.d9wG9L(agent/add-bitcoin-pulse-module-wiring-20260723-130500-866d04). Until then, resume it with/nix/store/9fri785m3f5v0vy40n51ih55kcrywg4l-tobserver-agent/bin/tobserver-agent resume <workspace>so a future profile switch cannot select the incompatible state-v2 helper.
Goal
Use the personal Codeberg account oibot for Tobserver change branches while preserving a human-only merge boundary:
mainaccepts changes only through pull requests;- direct, force, and deletion pushes to
mainare denied, including foroibot; - the agent can create and update pull requests without a write-capable Codeberg API token;
- a human merges through the Codeberg web UI;
- the agent never accesses or deploys to the live Tobserver machine.
The trade-off is accepted: Codeberg will attribute both agent-created pull requests and human merges to oibot, so there is no account-level distinction or independently enforceable approval by a second user.
Repository and distribution decision
The personal-only workflow will be implemented as a self-contained skill in the separate Agent Skills catalog rather than maintained as local skill and script copies in dotfiles.
- The canonical skill directory will be
~/Code/agent-skills/tobserver-change/. - The directory will contain
SKILL.md, thetobserver-agenthelper underscripts/, routing and execution evals, focused helper tests, and every reference or asset required to install, operate, validate, and recover the workflow. - The helper script will have one canonical source in the skill directory. Dotfiles may package or wrap that bundled script to expose
tobserver-agentonPATH, but must not retain a second editable copy. - The completed Agent Skills change will be pushed as an
oibotbranch and reviewed through a pull request inoibot/agent-skills; do not push directly to protectedmain. - Dotfiles will add the Agent Skills repository as a pinned, non-flake input and configure Pi to load both
create-skillandtobserver-changefrom that input. - The local
config/pi/skills/tobserver-changecopy and the upstreamanthropic-skills/skill-creatorinput will be removed after Pi successfully loads the catalog'stobserver-changeandcreate-skillskills. flake.lockwill pin the reviewed Agent Skills revision so a future catalog push cannot silently change Pi's active instructions or helper.- Existing local helper and skill files remain available during migration and are removed only after the catalog-backed installation passes local and end-to-end validation.
The intended order is: build and evaluate the standalone catalog skill, publish and review it, pin it in dotfiles, verify Pi and the packaged helper, complete the personal-only AGit cutover, and only then revoke or remove oibot-agent credentials.
Security invariants
- Protect
mainbefore changing credentials or helper behavior. - Do not place
oiboton a direct-push or branch-protection bypass list. - Do not expose an
oibotAPI token capable of merging pull requests or changing repository settings to the helper or agent. - Keep the existing workspace, branch-prefix, validation, secret, no-force-push, no-merge, and no-deployment checks.
- Keep the current bot credentials available for rollback until the personal-only workflow completes an end-to-end test.
- Do not delete keys, tokens, open pull requests, or active workspaces automatically.
Preconditions and decisions
- Confirm that independent Codeberg attribution and approval are no longer requirements.
- Confirm that human merging will happen only in the Codeberg web UI.
- Inspect existing open
oibot-agentpull requests; the public API returned none. - Check
tobserver-agent statusand preserve the active legacy workspace recorded above. - Establish an isolated Agent Skills branch and preserve existing dotfiles commits and owner work.
Phase 1: enforce the server-side merge boundary
In oibot/Tobserver repository settings, configure an exact protection rule for main:
- deny direct pushes for everyone, including repository owners;
- deny force pushes;
- deny branch deletion;
- require changes to arrive through pull requests;
- retain applicable status-check and conversation-resolution requirements;
- ensure there is no
oibotpush or bypass exception.
Verify the saved rule in the Codeberg UI. Do not probe Tobserver by attempting a push that could succeed if the rule is wrong. If a push-level test is desired, reproduce the rule in a disposable repository first.
Gate: do not continue until the UI confirms that oibot cannot directly update main.
Phase 2: prove a tokenless pull-request path
Use Forgejo AGit over SSH so pull requests can be created without an API write token:
git push origin HEAD:refs/for/main/<topic> \
-o title="<title>" \
-o description="<description>"
Before refactoring the helper:
- confirm
oibotauthenticates throughgit@codeberg.orgwith the personal SSH key; - confirm the public Codeberg API exposes the pull-request metadata needed by
revisewithout authentication; - determine the exact AGit representation of the topic, head ref, and pull-request URL;
- determine a robust multiline Markdown description encoding supported by Codeberg;
- create a clearly labeled AGit test pull request from an empty commit so it has no tree changes;
- push a second linear empty commit with the same topic and verify that it updates the same pull request without force-pushing;
- close the test pull request manually in Codeberg.
Do not merge the test pull request.
Gate: if AGit creation, URL discovery, or linear revision cannot be made reliable without a write-capable personal API token, stop and reconsider the account-removal design.
Phase 3: refactor tobserver-agent
Target file: ~/Code/agent-skills/tobserver-change/scripts/tobserver-agent
Identity and credentials
- change the push URL from
git@codeberg-tobserver-agent:oibot/Tobserver.gitto the normal personal Codeberg SSH endpoint; - retain an informational agent-specific commit author name;
- replace the bot noreply email with an agreed
oibot-compatible address; - remove bot Keychain account/service constants;
- remove write-token loading and temporary authorization-header handling;
- use unauthenticated HTTPS only for public read operations.
Pull-request creation
- replace API
POST /pullscreation with one AGit push; - generate a unique, shell-safe AGit topic tied to the existing
agent/*branch/workspace identity; - pass the validated title and Markdown body without unsafe quoting, truncation, or accidental shell interpretation;
- capture and validate the returned pull-request URL under
https://codeberg.org/oibot/Tobserver/pulls/; - preserve the workspace when AGit submission or URL discovery fails.
Pull-request revision
- replace the
oibot-agentauthor assertion with checks appropriate to the new model: canonical repository, open state,mainbase, expected AGit topic/head, and helper-compatible history; - fetch revision metadata without a write-capable token;
- push additional commits using the same AGit topic;
- preserve normal fast-forward/linear updates and continue to forbid force-push;
- verify that updating a pull request cannot create a duplicate PR silently.
Existing safety checks
Retain and regression-test:
- helper-created temporary workspaces only;
- exact canonical fetch and push endpoints;
agent/*local branch naming;- refusal to work on
main; - no SOPS payload changes or plaintext secret access;
- Nix formatting, flake evaluation, derivation evaluation, Git whitespace, and Gitleaks checks;
- no merge, deployment, live-server access, force-push, remote branch deletion, or automatic failed-workspace cleanup.
Phase 4: update the Tobserver skill and evaluations
Target files:
~/Code/agent-skills/tobserver-change/SKILL.md~/Code/agent-skills/tobserver-change/evals/evals.json
Changes:
- remove the dedicated-bot compatibility requirement;
- replace the bot SSH alias with the normal Codeberg SSH endpoint;
- describe protected
mainplus human web merge as the approval boundary; - state that the helper must not use a write-capable Codeberg API token;
- replace bot-owned PR revision checks with canonical AGit topic/head checks;
- retain the
agent/*, no-force-push, no-merge, no-deploy, and recoverability constraints; - update eval expectations that currently require
oibot-agentownership; - add or revise an eval covering rejection of direct
mainpushes and API-based merge attempts.
Phase 5: validate locally
- run
bash -n tobserver-change/scripts/tobserver-agentfrom the Agent Skills repository; - run focused helper tests for branch/topic restrictions, AGit metadata, push-option encoding, URL validation, and revision matching;
- test failure paths with mocked Git/HTTP commands so failed submission preserves the workspace;
- run the repository's Nix checks without deploying or building a Tobserver system closure;
- inspect the Agent Skills diff for credentials, token remnants, unrelated edits, and stale bot assumptions;
- rerun the
tobserver-changerouting and representative workflow evaluations.
Phase 6: end-to-end cutover test
With bot credentials still intact for rollback:
- create a fresh helper workspace;
- make an empty or harmless non-system test commit;
- run all helper checks;
- submit through AGit as
oibot; - verify that one PR targets
mainand no directmainupdate occurred; - revise the same PR with one additional linear commit;
- verify that no duplicate PR or force-push occurred;
- close the test PR manually without merging;
- verify failed and interrupted workspaces remain resumable.
Gate: retire the bot only after the complete create-and-revise workflow passes.
Phase 7: retire bot credentials
Perform these as explicit human-approved cleanup steps:
- remove
codeberg-tobserver-agentfrom~/.ssh/config; - unload
~/.ssh/oibot-agentfromssh-agent; - revoke the bot API token in Codeberg;
- remove the bot token from macOS Keychain;
- remove the bot SSH key from Codeberg;
- remove
oibot-agentrepository access; - archive or delete the bot account only after confirming it owns no required issues, PRs, repositories, or audit artifacts;
- delete local bot key files only with separate explicit confirmation and after any desired backup.
Do not rewrite historical commits or pull requests merely to remove the bot name.
Rollback
Until Phase 7:
- restore the previous helper push URL and bot token path;
- restore the skill's bot-identity requirements;
- use the preserved bot SSH alias and token;
- resume preserved helper workspaces rather than recreating changes;
- keep
mainprotection in place throughout rollback.
After bot credentials are revoked, rollback requires issuing a new constrained credential or restoring the bot account deliberately; do not weaken main protection as a shortcut.
Completion criteria
oibotcannot directly, forcibly, or destructively updatemain.- The helper creates and linearly updates a single PR through SSH/AGit.
- The helper and agent have no write-capable Codeberg API token.
- Only a human web action merges a PR.
- All existing local checks and secret boundaries still pass.
- No live Tobserver access or deployment occurred.
- Bot credentials and access are removed only after successful cutover and explicit approval.