Repository navigation
Releases: cfaysal/kherep
Release list
Kherep 0.4.0
Added
-
Codex fork refusal metadata (issue #477). A JSON-RPC error response to
initialize,thread/read,thread/turns/listorthread/forkduring a
fork attempt is now recorded as one content-free daemon log line:
kherep-node: Codex fork helper refused <method> (code <code|none>, <shape>, sha256 <12 hex>, mentions <list|none>). The code appears only when it is an
integer; the shape ismissing,empty,textoroverlong; the hash is
the first 12 hex digits of the SHA-256 of the message; the mentions say
which of the owner id, the newest turn id, the working directory, the Codex
home and the wordkherepthe message contains. No text of the message
enters the attempt, the audit, the log or the relay, no file holds it, and no
persisted field is added: the attempt's reason code,wake.jsonl,doctor
and the relay are unchanged. A throwing logger changes neither the reason,
the close nor the service admission lease. -
Intake visibility (refs #441).
kherep-node doctoradds theintakeLatency
check: for messages stored in the last two hours,observed,
maxLatencySeconds(control-plane accept to local store),overThreshold
(over 300 seconds; any one fails the check) andlastReceivedAt, with no
ids, text or sender names. It sees only messages that reached the inbox, so
it is no proof that the control-plane queue for the node drains. The daemon
logs a lane item over 5 seconds with its kind (lane chain item command:session.start took 61.0 s), a message stored more than 60 seconds
after the control plane accepted it with its id and lane wait, and a
synchronous child process over 2 seconds by name (process-start,
process-relations,owner-identity,owner-observe); never bodies,
session names or pids. -
Codex idle evidence (issue #408, first increment). The node's record of each
Codex session (codex-sessions/<id>.json) now keepslastEventand
lastEventAt, the last hook event (SessionStart,UserPromptSubmit,
PostToolUseorStop) and its time, andlastStopAt, the time of the last
Stop; an input without a known event keeps them. The original owner's
PostToolUserefreshes only the event of an existing record, and a
subagent's call writes nothing. The pureidleEvidence()reads a record as
idle only for aStopat least 90 seconds old of a session seen within 12
hours; a record of an older hook is never idle. Nothing acts on it yet:
msg sessionsprintslast event <event> at <time>for this node's Codex
sessions, andkherep-node doctoradds thecodexSessionscheck with counts
per last event and no session ids. Message delivery is unchanged. -
Codex fork reply policy, attempt store and admission (issue #408, second
increment; nothing is wired and no process is started). The opt-in
wake.codexForkpolicy section (enabled,sessionsby full thread id
only,platforms["darwin"]only,idleAfterSeconds30 to 3600, default
90,maxAnswerBytes256 to 8192, default 4096) is off when absent; any
malformed shape turns off only the fork reply and leaves the rest ofwake
as written. A new attempt store (codex-fork-attempts/<owner>/<message>.json)
claims each message once with an exclusive create, moves states forward only,
fails every read closed and turns launching or running attemptsuncertain
at recovery. A new admission decides the guards of the design in order with
one reason code and spends the owner's turn budget only when every other
guard passed; it refuses unless the Codex delivery hook is installed on
PostToolUse, reads a hook payload'spermission_modebefore the recorded
one and treatslastSeenas approximate. Idle evidence now fails closed on
Stopcontinuations: the CodexStophook marks the session record with
lastStopEndedafter recording theStop, on every exit that returns no
blocking continuation, every hook event clears the mark, and
idleEvidence()requires it, so a blockingStopor a failed mark is never
idle. The attempt store skips dotfiles such as.DS_Store, and
codexFork.sessionsids are matched without case and kept in lowercase.kherep-node doctorprints a
writtenwake.codexForksection with a count of opted-in sessions and fails a
rejected one. New audit actionsfork,fork-declined,fork-failed,
fork-uncertain,fork-superseded,fork-not-idleand
fork-disabled-platformexist for the later increments; nothing writes them yet. -
Codex fork reply producer (issue #408, third increment, darwin only, behind
wake.codexFork; nothing changes while the section is absent, except that
relays made while it was present are still withdrawn when the owner reads and
cleaned up after 24 hours; nothing is sent, forked or audited). For a
wake-authorized owner listed incodexFork.sessionswith idle evidence and
an accepted exact-addressed message, the daemon starts one short-lived
codex app-serverof thecodexonPATHper message, one at a time on the
node, in its own process group and withKHEREP_CODEX_FORK=1. It reads the
owner without loading it (thread/read, the newest turn through
thread/turns/list, which must be completed, and a goal check through
thread/goal/getthat refuses an active, paused or otherwise unfinished
goal, and refusesgoals-disabledwhen goals are off in the identity's Codex
config), forks it ephemerally and read-only at that turn with tools, hooks,
goals, web search, request-user-input and every discovered MCP server off,
and asks one structured answer only afterthread/goal/geton the fork
answers-32600with exactlyephemeral thread does not support goals: <fork id>(measured on 0.160.1, 0.162.0-alpha.17.2 and 0.163.0); any other
answer,goal: nullincluded, fails the attempt with reasonfork-goaland a
fixed detail code. Nocodexversion or hash is pinned; the feature list is
cached per resolved path and hash.deferGoalContinuationis not sent: both
measured binaries reject it with an ephemeral fork, and it copies the goal
into a persisted fork. The feature keys are filtered through
codex features list(stagesstable,experimental,under development,
deprecatedandremoved, as listed by the measured binaries; a removed key
is not used) and the attempt is refused when that listing fails or shows any
other line, or the MCP listing fails. Server requests are refused with-32601and fail the
attempt, as do tool items, goal notifications for the fork and turns the
helper did not start, whenever they arrive, also afterturn/completedor
while the helper closes; a timed-out turn or any violation, also one detected
while the helper closes, ends with SIGKILL of the helper's process group,
and that kill confirms the close only when the OS reports it sent or the
group absent; a failed or throwing group kill ends the attempt
uncertain/close-unconfirmedwith the service admission retained.
The validated answer is stored in the attempt file
(codex-fork-attempts/<owner>/<message>.json, mode 0600) with a fixed
reasoncode for every other outcome; nothing is relayed, and the owner's
inbox record, progress, session record and thread stay unchanged. The fork
spends the owner's autonomous-turn budget once per attempt and writes one
wake.jsonlline; on another platform the only effect is a
fork-disabled-platformline. The daemon now marks launching or running
attemptsuncertainat start, the Codex delivery hook does nothing inside a
fork helper, andkherep-node doctoradds thecodexForkAttemptscheck
(counts per state, no ids). The JSON-RPC client of the native Queue cleanup
moved tocodex-app-server-client.mts; it now decodes UTF-8 split across
output chunks exactly (a split multibyte character came back as replacement
characters before) and refuses every server request with-32601. -
Codex fork reply relay (issue #408, fourth increment, darwin only, behind
wake.codexFork). A completed fork answer is relayed as one labelled proxy
answer to the original's sender: a new optionalproxyOfonmessage.send
andmessage.delivernames the original, never together withinReplyTo,
so the original is never marked replied; the proxy is one reply hop deeper.
The daemon's sweep writes one outbox record per completed attempt and the
owner's local sidecarinbox/proxied/<message>.json; there is no stored
release, and the exchange sends the record only when the relay guards pass
at that send (attempt at most 24 hours old, the fresh policy with opt-in,
enrollment, kill switch, fingerprint, platform and answer bound, the Worker
capabilitymessaging.proxy.v1from adirectoryframe of the current
authenticated connection, the original still accepted, the owner's recorded
session idle with its task and permission guards) and the sidecar matches
the attempt. A relay spends no turn and starts no helper. The owner reading
or answering first withdraws the relay before any guard is consulted,
exactly when nothing can have left the node and as unconfirmed otherwise; a
held record without any Worker status is removed after 24 hours and the
outcome is then recorded as unresolved, never as not delivered. The
withdrawal and the cleanup run in every poll for every message with a
sidecar, whatever the owner's session state, and do not depend on the
section; a superseded relay whose sidecar is missing or names another relay
is cleaned up as well, and a record that is not the attempt's relay is never
removed. The owner's
delivery block andmsg inboxshow the relay state (prepared, queued or
awaiting confirmation, may have reached the control plane, queued by the
control plane, reached the peer, could not be delivered, unresolved); only a
proxy that reached the peer says not to answer again. The aud...
Kherep 0.3.0
Added
- Closed-session cwd refusal code (issue #396): a closed-session delivery that
the recorded working directory refuses (not absolute, missing, or outside
the workspace roots) now waits withwaiting/cwd-refusedinstead of
waiting/wake-not-authorized, andmsg statuson the sender says so. Nodes
advertisemessaging.progress.v2; the Worker sendswake-not-authorized
to a sender without it. Upgrade the Worker before the nodes: an older
Worker rejects the new code, and the target node retries the report. - Offer provenance (issue #417): an inbox record carries
offeredBy
(wake,prompt,stop,tool,codex-prompt,receive,codex-wake,
intercom,mcp) withofferedAt; the wake listener leaves
listeners/<session_id>.woke.json, which the woken turn's
UserPromptSubmitclaims within 30 s;msg statusandmsg inboxshow
offered by;msg status <id>now answers for a message in this node's
inbox (exit 0 instead of 1). - Managed node daemon service (issue #404):
kherep-node service install,
upgrade,statusandrollbackmanage a per-user macOS LaunchAgent or
Windows Scheduled Task from a verified immutable source pin. Upgrade and
rollback retain exact native definition and security backups, verify daemon
ownership, authenticated reconnection and loaded source identity, and refuse
service drift, unsafe adoption, uncertain process identity and active
descendants before stopping a service. The Windows task uses a fixed Node
supervisor that preserves the selected log, verifies the source before every
child start and restarts an exited daemon after 30 seconds. A generation-bound
one-use permit admits only the transaction's candidate while task admissions
are drained, and stop retains and terminates the selected supervisor before
its exact daemon child. Doctor now compares the daemon's
recorded startup source and verified hook pins with the invoking checkout. - Sender receipts (issue #402): when a message reaches
delivered(the target
session's turn that carried it completed), the sending session's next
delivery hook event shows one line,Your message <id> to <node>/<session> was received (confirmed <updatedAt>)., once per message (noticedAt), for
Claude Code and Codex senders. The time is when the sender's node recorded
delivered. A receipt matches the sender by session id (fromSessionId),
and byfromSessiononly for a record without it (an older sender), so a
renamed session still gets it and a later session reusing the name does not.
No receipt beforedelivered, nor when the message isrepliedor its reply
already arrived.
A receipt never wakes a session or continues a turn:Stopshows it only
beside messages or failure notices, and no wake entry or turn budget is used.
Receipts never cost a peer message slot or block: they take only the room
left after the messages and wait otherwise; more than 5 are
counted in one line. The intro names receipts, failures or both. Failure
notices are unchanged. Selection lives in
modules/control-plane/node/sent-notices.mts. - Observation result check: a new
SubagentStophook,obs-result-check.mts,
wired with matcherclaude-obs, checks the agent'sOBS-RESULTstatus line
throughclaude/hooks/lib/obs-result-policy.mts. The first non-empty line is
the onlyOBS-RESULTline;wrote <n> <ids>needs n positive and exactly n
numeric ids;emptyandfailedneed a reason whose first word is no status
word, which catchesfailed wrote 4 pages: .... A malformed line is sent
back to the agent once with a fixed instruction (decision: "block"); on the
continuation, and for a validfailed, the operator gets asystemMessage
instead. The message comes fromlast_assistant_message, else the agent
transcript. No message text reaches stdout, and any error is one
systemMessagewith exit 0. - Codex observation candidate check: a new Codex
SubagentStophook,
codex-obs-result-check.mts, wired with matchercodex-obsin the last hook
group of the managed block, checks the worker's candidate through
codex/hooks/obs-candidate-policy.mts: exactly one strict JSON document whose
only key is anobservationsarray, each candidate with exactlytitle,
bodyStorage,evidence,labelsandplacement. A fenced or otherwise
malformed candidate is sent back to the worker once (decision: "block"); on
the continuation the operator gets asystemMessageand the Maestro publishes
nothing. The message comes fromlast_assistant_message, else the subagent
rollout; when neither is visible the hook says so. It prints one JSON document
or nothing, never message text. An upgrade appends only this group, so every
existing positional trust key stays (issue #326). - Attribution log: a new git
pre-pushhook besidecommit-msgrecords one
line per pushed ref in the node's local
<config root>/control-plane/attribution.jsonl(mode0600) for
repositories under the workspace, and always exits 0. The session is
CLAUDE_CODE_SESSION_ID, elseKHEREP_SESSION_ID, else a marker the Codex
PreToolUsephase leaves for that repository within 120 seconds, else
unknown.gh pr createnever reaches git, so
modules/control-plane/node/attribution-hook.mtsrecords it at
PostToolUse, from the checkout, in Claude for Bash and PowerShell and in
Codex for the shell tools; the PR number comes from the tool output, else
gh pr view, else it staysnull. A record holds ids, owner/name, the
toplevel, branch, remote ref, SHA and PR number, never commit subjects, PR
text, tokens or the environment; every append drops records older than 90
days.kherep-node attribution [--branch] [--pr] [--repo] [--since <hours>] [--json]reads it. The token walk of the main-checkout guard moved to
claude/hooks/lib/command-walk.mtsand serves both hooks. - Main-checkout guard: a new
PreToolUsehook,main-checkout-guard.mts,
keeps the main checkout of a workspace repository (git-dir equals
common-dir) on its default branch, because sessions share it. It blocks
git checkout <ref>without--(a SHA included),checkout -b,-B,
--orphan,--detach, andgit switchto any branch other than the
default, including-c,-Cand--detach, with exit 2 and a pointer to
git worktree add <path> -b <branch>. File checkouts,restore,
worktree add,pull,fetch,merge,rebase, linked worktrees and
repositories outside the workspace pass. The default branch is
origin/HEAD, else a localmainormaster; without one it warns and
exits 0. The inlineKHEREP_MAIN_CHECKOUT=switchprefix, or
$env:KHEREP_MAIN_CHECKOUT='switch';in PowerShell, lets one approved
command through; a persistent variable is ignored. Claude runs it for Bash
and PowerShell in a newBash|PowerShellgroup; Codex runs it through the
hook adapter as the last entry of the shell group, so a block arrives as a
JSON deny. A new gitpost-checkouthook besidecommit-msgwarns, and
always exits 0, when a branch checkout leaves such a main checkout off its
default branch; it is silent in linked worktrees, afterworktree add,
during a rebase and with the marker.critical-file-integrity.mtsguards it
likecommit-msg(issue #325). - Confluence brokers: new read-only verb
list --space <key> [--title-contains <text>] [--label <name>] [--limit <n>]. It reads every
page of the space through the paginated v2 pages endpoint, filters titles by
case-insensitive substring in the broker, and filters by label through one
v1 CQL query that follows_links.next. It prints onepagerow per match,
thentotal:,shown:andtruncated:. The total is counted by reading
every result page, never taken fromtotalSize; only--limittruncates.
Exit 0 for any completed read, includingtotal: 0, and exit 1 for a
Confluence or argument error, which prints nototal:. The space index now
stops on a cursor that adds no new page, not only on an empty page
(issue #315). - Confluence brokers:
labels --id <page> --keep-runtime <runtime-label>
repairs a page that carries two runtime labels. It deletes the other one,
reads the labels back and printsruntime: kept,runtime: removedand
labels:; it exits 1 when the removed label is still there. It cannot be
combined with--labelsor--remove, and it refuses without writing when
the value is not aruntime-label, when the page carries one, none or more
than two runtime labels, or when the named label is not among them. The
labelsverb now lives in the sharedconfluence-label-cli.mts, which the
installers, drift checks and smoke test project beside the brokers
(issue #318). - Atlassian destructive guard: a new
PreToolUsehook,
atlassian-destructive-guard.mts, stops everymcp__<server>__executeDestructive
call, under any server name, the managedatlassianserver, a plugin
namespace and a claude.ai connector named by a UUID included. Claude asks the
operator to confirm the call (permissionDecision: "ask"), wired with
matchermcp__.*__executeDestructive. Codex hooks cannot ask, so Codex denies
it with--runtime codex; the guard is the last entry of the existing
Agent, web and MCPPreToolUsegroup, because a new group would move the
positional trust key of every operatorPreToolUsegroup after the managed
block. The installer recognises the exact block from immediately before the
guard and replaces it; Codex asks to review that one entry. Read and write
calls pass (issue #376). - Claude mid-turn delivery: the control-plane delivery hook also runs at
PostToolUse, as the last entry of the all-tools group, so a Claude Code
session in a running turn receives accepted peer messages next to the result
of its next successful tool call instead of only at th...
Kherep 0.2.0
Added
-
Control Plane: with
wake.replies: truethe messages of a task an idle
Claude Code session requested withmsg send <node> --newalso wake it
without a listing, so the task's plainmsg sendanswer, which carries the
task id and noinReplyTo, is not left waiting for the next user turn. The
grant needs the request to be dispatched, the message to come from the node
the task was dispatched to, the request to be at most 24 hours old, and the
requesting session's id, whichmsg send --newandtask newnow keep locally as
requestedBySessionIdand never sends to the Worker, to match (a request
without it matches byrequestedBy). It covers every message of the task,
bounded by the turn budget. Audit lines name"grant": "task", delivery
progress reports such messages like replies, and Codex requesters are out
of scope (issue #264). -
Control Plane: the optional node policy object
wake.budget
(perHour,perDay,spacingSeconds) sets the per-session budget of
autonomous turns, which stays 6 per rolling hour, 20 per rolling day and
30 s apart without it or for a missing field. Values must be integers within
hard bounds (perHour1 to 60,perDay1 to 500,spacingSeconds5 to
3600), an explicitperDayat leastperHour(without it the day allows at leastperHourturns); anything else, or an unknown key,
rejects the wholewakesection. The Claude Code wake listener, the Claude
and CodexStopcontinuations, the Codex task resume,codex queueand
closed-session delivery use the same effective budget, anddoctorshows it
aswakeBudget(issue #259). -
Control Plane: the opt-in node policy switch
wake.replies: truelets a
reply wake the idle Claude Code session that sent the original message,
without listing the session;sessionsmay then be empty. The grant needs
the reply to come from the node the original was sent to, the original to
be at most 24 hours old and not refused, expired or error, and the sending
session's id, whichmsg sendnow keeps locally asfromSessionIdand never
sends to the Worker, to match (a sent record without it matches by name).
Every other wake guard still applies; audit lines name"grant": "reply",
delivery progress reports such replies, anddoctorshows the switch. A
non-boolean value turns waking off. Codex wake paths are unchanged
(issue #253). -
Control Plane:
GET /healthalso returns the bundled productversion,
an optional deploy-time sourcecommit(--define KHEREP_BUILD_COMMIT) and
remoteMcp, still without authentication or configuration values. Existing
fields are unchanged (issue #215). -
Control Plane:
kherep-node doctorprints a JSON report on enrollment and
key, daemon liveness, Worker reachability and version, policy and wake
summary, installed runtimes and versions, hook paths against this checkout
and live wake listeners, and exits 1 when a check fails. The daemon now
writesdaemon.json(pid, start, last authenticated connection and lost
connection time) for it (issue #215). -
Control Plane:
kherep-node doctorreports each runtime'sreadyfrom the
daemon's last readiness probe instead of"not available":true, or
falsewith the fixedcause(sign-in,timeout,error), each with
probedAtandaged(older than the daemon's 10 or 2 minute revalidation
bound), or"unknown"when the daemon is not running or has not probed that
runtime. Doctor never probes. A runtime the sessions policy names whose last
probe needs a sign-in fails theruntimescheck. The daemon records each
completed probe indaemon.jsonasreadiness.<runtime>, without the
probe's output (issue #222). -
Control Plane: a runtime readiness probe (issue #197).
claude auth status
reportedloggedIn: truefor an expired login, so the node checks each
enabled runtime with a real minimal call:claude -p --safe-mode --no-session-persistence --tools ""with a one-line system prompt, and
codex -c features.hooks=false exec --ephemeral --sandbox read-onlywith the
user's config, no hooks and its MCP servers disabled as for intercom runs. It probes once at daemon start;
afterwards a verdict is used stale while it revalidates in the background
(ready after 10 minutes, not ready after 2, also from the session round; 45
second timeout), and no probe runs on the daemon's frame lane. A ready
runtime is advertised asruntime.claude.ready.v1or
runtime.codex.ready.v1. For a runtime that is not signed in, a task start
or continue fails withtarget runtime <runtime> not ready (sign-in required)and starts nothing, and a message that a closed-session delivery
or a Codex message resume would carry isrefusedwith that reason instead
ofdelivered. A probe that timed out or failed otherwise blocks no task;
messages wait withretry-pending. -
Control Plane: a task or intercom run without first turn progress 10
minutes after its start is stopped and reportedfailedwithno progress after start(issue #197). The messages a Claude intercom run carried are
refused withtarget run made no progress after start; those of a Codex run
get thewake-failedprogress and are offered again within the offer limit. -
Control Plane:
msg statusandmsg send --waitshow the sender states
runningandstopped, derived from the existing accepted progress codes
without a new wire state, and an accepted message without progress for 5
minutes gets a fixed actionable reason (issue #197). Messages for Codex task
sessions now carry a progress code while the task is busy, stopped by its
operator, held by a wake guard, failing to resume or running. -
Control Plane: the MCP
statustool also returnssenderState(running,
stoppedor the canonical state, from the samesenderStatefunction as
msg status) and, for an accepted message without progress for 5 minutes,
a fixedhint(issue #197). Thestatefield is unchanged. -
Control Plane: a Codex intercom run the node started on its own is listed
withkindcodex-intercominstead ofcodex-task, so the MCPsessions
tool tells it apart from a requested task;msg sessionsmarks both as
[background task](issue #198). -
Control Plane: an idle Claude Code session wakes after a restart without any
user input (issue #101). ASessionStartinput withoutpermission_mode
and without a stored mode now takes the mode of the last user entry in the
session transcript (transcript_path, the last 2 MiB, only the
permissionModefield, a regular file underprojects/of the Claude
config directory;node/transcript-mode.mts) and stores it. A missing,
foreign or unreadable transcript, orbypassPermissionsthere, still
refuses; the listing, settings and launch flag checks run as before. The
listener armed there also wakes once, after 8 s, for messages that arrived
while no listener ran (auditbacklog), each at most once and under the
same guards and budget; a prompt within those 8 s supersedes it. -
Control Plane: a message for a session of this node that is no longer
running is still handled when the node policy sets
messaging.resumeClosed: true(issue #102, default off). The daemon
resumes the known session in the background in its recordedautoor
defaultmode (Claude Codeclaude --resume <id> --bg, Codex
codex exec resume <thread>) with the fixed wake text, so the message
arrives as framed peer content, or otherwise starts an intercom session
with the closed session's runtime and working directory and a directive
that names the automatic fallback. The guards of--newand the wake apply
fail closed (kill switch, sessions and runtime,delegate.acceptand the
accept rules, reply depth, neverbypassPermissions,maxConcurrent,
workspace roots, the session's turn budget), a message causes one attempt
at most, and every outcome is audited inwake.jsonlasclosed-session
resumed,neworrefusedwith the reason. Every successful listing is
kept for 7 days inknown-sessions.json. -
Control Plane: a message for a closed session goes to one intercom session
per sender session instead of resuming the closed session, whose whole
conversation a resume would reload (issue #105). The newest intercom session
the node started itself for the same sender (requestedBy
<node id>/<session>) gets it: a running one through its delivery hook and
wake, the message readdressed to it (closedTokeeps the closed session)
and its task grant extended to the messages of that sender; an ended one is
resumed in the background (claude --resume,codex exec resume). Only
without such a session, or when its resume fails, a new one starts. The
closed session itself is no longer resumed. Every message now carries its
threaded reply command: a new intercom session gets the messages framed as
the delivery hook frames them, each with
<cli> msg send --reply-to <message id> -- <reply text>, and is told to
answer with it, as the hook and the Codex resume already frame it. The
guards stay fail closed; the audit outcomeresumedis replaced by
reused(with the intercom session'staskId), next tonewand
refused. -
Control Plane: the Claude Code wake listener is armed at
SessionStarttoo
(issue #97), so an idle session is wakeable again after its process
restarts (app restart,--resume,--continue,/clear, fork) without
waiting for the user to type. The installer adds the entry last to the
SessionStarthooks with the sameasyncRewakeand timeout. A following
prompt supersedes that listener as before. Aftercompactthe session
counts as busy, because auto-compaction runs inside a turn. ASessionStart
input carries nopermission_mode, so the listener arms there only when,
fail closed, the mode the session's last ...
Kherep 0.1.2
Added
- A
searchverb for the Confluence brokers. It runs a read-only semantic
search filtered to the configured space and reports a hit, no match or an
unavailable search as distinct exit codes (0, 1, 2). - An evidence-first gate for Claude. A
UserPromptSubmithook asks for
research on relevant prompts, naming the knowledge space and, inside a Git
repository, the code graph. AStophook sends a substantial turn back once
when it shows neither a lookup nor the visible classification
[research: none - <reason>]. Trivial turns are not gated, a continuation
is never blocked twice, and an unreadable transcript fails open. Skills
listed in the optional operator file<claude-home>/kherep/research-sources.json
count as lookups.
Changed
- Codex observations no longer surface as a visible Stop continuation after a
reinstall. Both hosts project an acceptance-onlyStopgroup; the
UserPromptSubmitMaestro context hook reminds the Maestro quietly to
dispatchcodex-obsonce per main turn. Earlier managed Stop groups with an
observation step are upgraded in place.
Kherep 0.1.1
Added
- A commit policy file next to the
commit-msghook. The work-item rule now
applies to every runtime that runs Git, not only to a process that carries
theKHEREP_*variables.KHEREP_WORK_ITEM_REQUIREDand
KHEREP_WORK_ITEM_PATTERNgiven at install time are persisted; a variable
set at commit time still overrides the file. labels --removefor the Confluence brokers, with a read-back of the labels
that remain on the page.
Changed
- The installer manages only a marked reference block in the workspace
CLAUDE.mdandAGENTS.md. Text outside the block stays byte-identical;
unedited copies of the previous full template are replaced by the block. The
block points to the user-level rules instead of repeating them. - The Confluence brokers and the modules they import are installed together
with the observation agent.KHEREP_INSTALL_ATLASSIAN_TOOLSnow only adds
the Jira and MPAC helpers. - The Claude observation agent has its own definition: it files through the
Claude broker only, starts every result with anOBS-RESULTstatus line,
keeps findings under a hierarchy node named in the brief and takes the
session label from the brief. The Codex worker contract moved to
codex/agents/codex-obs.md. - The drift check compares only the managed block of the workspace rule files
and includes the commit policy file.
Kherep 0.1.0
First public release.
Added
- Maestro agent orchestration: plan work, delegate focused tasks and verify the
combined result against code, tests and the requested outcome. - Claude Code adapter with an installer that backs up and can roll back the
managed configuration, an isolated preview mode and a read-only drift check. - Codex adapter with its own installer, an installation receipt and the
kherep-maestroplugin. - Shared rules, hooks, skills and agents for implementation, review, debugging
and delivery. - Model and tool routing through operator-configured policies.
- MCP integration through transport and authentication adapters for explicitly
configured services. - Local inference through configured local processing routes, including a
separate path for private inputs. - Central Brain, a shared knowledge base in a dedicated Confluence space. The
Claude and Codex observation agents file durable findings from completed
turns as pages through the service-account brokers. - Turn-completion observations for Claude and Codex through the service-account
Confluence path.