Changed
-
BREAKING:
akb initinside a git repository refuses until the KB's versioning mode is
chosen. The invocation exits 2 naming the repository it found and what each flag does:
--embedputs the KB into that repository's history — akb commits onlykb/,raw/and
.agent-kb/, never the host's other worktree changes — and--no-gitleaves the KB
unversioned and out of the host'sgit statusthrough.git/info/exclude, a file local
to the clone. Previously the same invocation created a repository nested inside the
host's, andakb initwroteuser.nameinto it. A KB that is not inside a repository is
unchanged:akb init <name>with no flag still creates a repository of its own. -
The versioning mode is recorded in
.agent-kb/akb.yamlasversioning: gitor
versioning: none, written explicitly at init in both modes. A config that predates
the key meansgit— the mode those bases were created in — so an existing KB keeps
working unchanged; any other value is rejected rather than read as git, so a misspelled
mode never commits under the wrong assumption. Anonebase invokes no git at all:
mutations write their files and stop, the base takes its lock on.agent-kb/akb.lock
instead of on the host repository, andakb statusreportsVersioning: nonein place of
the git line.--no-commitis a no-op there, as it is for any base that never commits. -
Commit identity resolves from the environment, then the base, then git, and is exported
to the commit instead of passed as-c user.name=….AKB_AUTHOR_NAME/AKB_AUTHOR_EMAIL
win, thengit-author/git-emailin the base'sakb.yaml, then git's own resolution
(GIT_AUTHOR_*in the environment, then the merged repository and global configuration).
An identity akb supplies is exported asGIT_AUTHOR_*andGIT_COMMITTER_*; when it
supplies none, git resolves the identity itself, which leaves a user-setGIT_AUTHOR_*
working as a documented escape hatch. No source naming an identity is a usage refusal
(exit 2) that fires before anything is written, replacing the raw
Committer identity unknownfatal an agent could only hit after its page was staged. -
A mutation blocked by an in-progress merge is refused up front instead of failing at
the commit. Detecting a clean in-progress merge (MERGE_HEAD), not only unmerged paths,
closes the gap where agit status --porcelainscan passed and
fatal: cannot do a partial commit during a mergesurfaced after the page had been
written and staged. The refusal names the host repository and the path it changed, and
states that the merge belongs to the host project rather than to the KB. -
Every mutating command goes through one mode-aware storage helper.
storage.OpenStore
selects the provider from the recorded mode and owns the lock, the identity and merge
preflight, and the commit, replacing the hardcodedNewGitProvidercall sites and the
directLockRepo/CommitFiles/NothingToCommitcalls across the command packages. The
base lock is now held across thekb/log.mdappends too.
Added
-
akb initgained--embed,--no-git,--force,--author-name/--author-email,
andakb init ..--forcebypasses the refusal to write.agent-kb/,kb/and
raw/directly into a repository root; it selects no versioning mode, so a repository-root
invocation still names one (akb init . --embed --force).--author-name/
--author-emailsupply the init commit's identity for that commit only and are never
written toakb.yaml: the akb default (agent-kb <agent@agent-kb>) is recorded there
only when neither the environment nor git config names an identity, because an identity
baked into a file that travels with the base would be mis-attributed after a clone.
akb init .initializes the directory it runs in and adopts that directory's basename as
the KB name, reported on the exit-0 line.akb inithonors--no-commit: it scaffolds and
stages the base and leaves the commit to the caller, so an orchestrator can bundle init
with templates and an overview into one commit. -
KNOWN-LIMITATIONS.mdrecords that a KB cannot be a git submodule of the host
project, with the reason (a base's repository is local to the machine that initialized
it and akb has no remote or push machinery, while git refuses the local-path clone form
since CVE-2022-39253:fatal: transport 'file' not allowed) and the supported answers
(--embed,--no-git, or a human-rungit submodule addover a hosted repository).
Fixed
-
akb initno longer clobbers an existing.gitignore. Both files it writes append
the lines they need and keep every rule already there, so re-running init over a
directory that carries an ignore file is safe instead of destructive. -
Repository-root
.git/info/excludeentries are anchored with a leading slash
(/.agent-kb/,/kb/,/raw/). Unanchored, they also matched a same-named directory
anywhere below the root, hiding unrelated host files fromgit status. -
The integration suite no longer takes its git identity from the machine it runs on.
Onceakb initstopped writing repo-localuser.name(identity moved toakb.yaml),
the testscripts that shell out to rawgit commithad no git-visible identity of their
own: they passed on hosts whose system-level git config supplies one (NixOS does, even
withHOMEmoved) and failed on CI runners, which have none. The testscriptSetup
now injects an ambientGIT_CONFIG_*identity every scenario inherits; scenarios that
exercise identity resolution itself override or empty those same slots. The release
preconditions gained a test gate that runs the suite under a CI-simulated git
environment (no system or global config, no identity environment), so a
machine-dependent scenario blocks the tag instead of the published release workflow. -
A
--no-gitbase at a repository root no longer writes a root.gitignorefor
exclusions the host's exclude file already carries. -
An invocation with nothing to record no longer fails on a commit identity it would
never use.akb raw sync,akb index removeandakb template writesettle the
no-change case under the base lock before the preflight; a sync that finds nothing also
stops rewriting the manifest. -
Post-write failure guidance is mode-accurate: an unversioned base is no longer told to
resolve a merge or finish a commit by hand.