Skip to content

Releases: cfaysal/kherep

Kherep 0.4.0

Choose a tag to compare

@cfaysal cfaysal released this 18 Oct 12:52

Added

  • Codex fork refusal metadata (issue #477). A JSON-RPC error response to
    initialize, thread/read, thread/turns/list or thread/fork during 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 is missing, empty, text or overlong; 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 word kherep the 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 doctor adds the intakeLatency
    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) and lastReceivedAt, 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 keeps lastEvent and
    lastEventAt, the last hook event (SessionStart, UserPromptSubmit,
    PostToolUse or Stop) and its time, and lastStopAt, the time of the last
    Stop; an input without a known event keeps them. The original owner's
    PostToolUse refreshes only the event of an existing record, and a
    subagent's call writes nothing. The pure idleEvidence() reads a record as
    idle only for a Stop at 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 sessions prints last event <event> at <time> for this node's Codex
    sessions, and kherep-node doctor adds the codexSessions check 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.codexFork policy section (enabled, sessions by full thread id
    only, platforms ["darwin"] only, idleAfterSeconds 30 to 3600, default
    90, maxAnswerBytes 256 to 8192, default 4096) is off when absent; any
    malformed shape turns off only the fork reply and leaves the rest of wake
    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 attempts uncertain
    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's permission_mode before the recorded
    one and treats lastSeen as approximate. Idle evidence now fails closed on
    Stop continuations: the Codex Stop hook marks the session record with
    lastStopEnded after recording the Stop, on every exit that returns no
    blocking continuation, every hook event clears the mark, and
    idleEvidence() requires it, so a blocking Stop or a failed mark is never
    idle. The attempt store skips dotfiles such as .DS_Store, and
    codexFork.sessions ids are matched without case and kept in lowercase. kherep-node doctor prints a
    written wake.codexFork section with a count of opted-in sessions and fails a
    rejected one. New audit actions fork, fork-declined, fork-failed,
    fork-uncertain, fork-superseded, fork-not-idle and
    fork-disabled-platform exist 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 in codexFork.sessions with idle evidence and
    an accepted exact-addressed message, the daemon starts one short-lived
    codex app-server of the codex on PATH per message, one at a time on the
    node, in its own process group and with KHEREP_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/get that refuses an active, paused or otherwise unfinished
    goal, and refuses goals-disabled when 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 after thread/goal/get on the fork
    answers -32600 with exactly ephemeral 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: null included, fails the attempt with reason fork-goal and a
    fixed detail code. No codex version or hash is pinned; the feature list is
    cached per resolved path and hash. deferGoalContinuation is 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 (stages stable, experimental, under development,
    deprecated and removed, 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 -32601 and fail the
    attempt, as do tool items, goal notifications for the fork and turns the
    helper did not start, whenever they arrive, also after turn/completed or
    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-unconfirmed with the service admission retained.
    The validated answer is stored in the attempt file
    (codex-fork-attempts/<owner>/<message>.json, mode 0600) with a fixed
    reason code 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.jsonl line; on another platform the only effect is a
    fork-disabled-platform line. The daemon now marks launching or running
    attempts uncertain at start, the Codex delivery hook does nothing inside a
    fork helper, and kherep-node doctor adds the codexForkAttempts check
    (counts per state, no ids). The JSON-RPC client of the native Queue cleanup
    moved to codex-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 optional proxyOf on message.send
    and message.deliver names the original, never together with inReplyTo,
    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 sidecar inbox/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
    capability messaging.proxy.v1 from a directory frame 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 and msg inbox show 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...

Read more

Kherep 0.3.0

Choose a tag to compare

@cfaysal cfaysal released this 15 Oct 18:19

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 with waiting/cwd-refused instead of
    waiting/wake-not-authorized, and msg status on the sender says so. Nodes
    advertise messaging.progress.v2; the Worker sends wake-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) with offeredAt; the wake listener leaves
    listeners/<session_id>.woke.json, which the woken turn's
    UserPromptSubmit claims within 30 s; msg status and msg inbox show
    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, status and rollback manage 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 by fromSession only 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 before delivered, nor when the message is replied or its reply
    already arrived.
    A receipt never wakes a session or continues a turn: Stop shows 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 SubagentStop hook, obs-result-check.mts,
    wired with matcher claude-obs, checks the agent's OBS-RESULT status line
    through claude/hooks/lib/obs-result-policy.mts. The first non-empty line is
    the only OBS-RESULT line; wrote <n> <ids> needs n positive and exactly n
    numeric ids; empty and failed need a reason whose first word is no status
    word, which catches failed 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 valid failed, the operator gets a systemMessage
    instead. The message comes from last_assistant_message, else the agent
    transcript. No message text reaches stdout, and any error is one
    systemMessage with exit 0.
  • Codex observation candidate check: a new Codex SubagentStop hook,
    codex-obs-result-check.mts, wired with matcher codex-obs in 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 an observations array, each candidate with exactly title,
    bodyStorage, evidence, labels and placement. A fenced or otherwise
    malformed candidate is sent back to the worker once (decision: "block"); on
    the continuation the operator gets a systemMessage and the Maestro publishes
    nothing. The message comes from last_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-push hook beside commit-msg records one
    line per pushed ref in the node's local
    <config root>/control-plane/attribution.jsonl (mode 0600) for
    repositories under the workspace, and always exits 0. The session is
    CLAUDE_CODE_SESSION_ID, else KHEREP_SESSION_ID, else a marker the Codex
    PreToolUse phase leaves for that repository within 120 seconds, else
    unknown. gh pr create never reaches git, so
    modules/control-plane/node/attribution-hook.mts records 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 stays null. 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.mts and serves both hooks.
  • Main-checkout guard: a new PreToolUse hook, 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, and git switch to any branch other than the
    default, including -c, -C and --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 local main or master; without one it warns and
    exits 0. The inline KHEREP_MAIN_CHECKOUT=switch prefix, 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 new Bash|PowerShell group; 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 git post-checkout hook beside commit-msg warns, and
    always exits 0, when a branch checkout leaves such a main checkout off its
    default branch; it is silent in linked worktrees, after worktree add,
    during a rebase and with the marker. critical-file-integrity.mts guards it
    like commit-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 one page row per match,
    then total:, shown: and truncated:. The total is counted by reading
    every result page, never taken from totalSize; only --limit truncates.
    Exit 0 for any completed read, including total: 0, and exit 1 for a
    Confluence or argument error, which prints no total:. 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 prints runtime: kept, runtime: removed and
    labels:; it exits 1 when the removed label is still there. It cannot be
    combined with --labels or --remove, and it refuses without writing when
    the value is not a runtime- label, when the page carries one, none or more
    than two runtime labels, or when the named label is not among them. The
    labels verb now lives in the shared confluence-label-cli.mts, which the
    installers, drift checks and smoke test project beside the brokers
    (issue #318).
  • Atlassian destructive guard: a new PreToolUse hook,
    atlassian-destructive-guard.mts, stops every mcp__<server>__executeDestructive
    call, under any server name, the managed atlassian server, 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
    matcher mcp__.*__executeDestructive. Codex hooks cannot ask, so Codex denies
    it with --runtime codex; the guard is the last entry of the existing
    Agent, web and MCP PreToolUse group, because a new group would move the
    positional trust key of every operator PreToolUse group 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...
Read more

Kherep 0.2.0

Choose a tag to compare

@cfaysal cfaysal released this 08 Oct 11:17

Added

  • Control Plane: with wake.replies: true the messages of a task an idle
    Claude Code session requested with msg send <node> --new also wake it
    without a listing, so the task's plain msg send answer, which carries the
    task id and no inReplyTo, 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, which msg send --new and task new now keep locally as
    requestedBySessionId and never sends to the Worker, to match (a request
    without it matches by requestedBy). 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 (perHour 1 to 60, perDay 1 to 500, spacingSeconds 5 to
    3600), an explicit perDay at least perHour (without it the day allows at least perHour turns); anything else, or an unknown key,
    rejects the whole wake section. The Claude Code wake listener, the Claude
    and Codex Stop continuations, the Codex task resume, codex queue and
    closed-session delivery use the same effective budget, and doctor shows it
    as wakeBudget (issue #259).

  • Control Plane: the opt-in node policy switch wake.replies: true lets a
    reply wake the idle Claude Code session that sent the original message,
    without listing the session; sessions may 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, which msg send now keeps locally as fromSessionId and 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, and doctor shows the switch. A
    non-boolean value turns waking off. Codex wake paths are unchanged
    (issue #253).

  • Control Plane: GET /health also returns the bundled product version,
    an optional deploy-time source commit (--define KHEREP_BUILD_COMMIT) and
    remoteMcp, still without authentication or configuration values. Existing
    fields are unchanged (issue #215).

  • Control Plane: kherep-node doctor prints 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
    writes daemon.json (pid, start, last authenticated connection and lost
    connection time) for it (issue #215).

  • Control Plane: kherep-node doctor reports each runtime's ready from the
    daemon's last readiness probe instead of "not available": true, or
    false with the fixed cause (sign-in, timeout, error), each with
    probedAt and aged (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 the runtimes check. The daemon records each
    completed probe in daemon.json as readiness.<runtime>, without the
    probe's output (issue #222).

  • Control Plane: a runtime readiness probe (issue #197). claude auth status
    reported loggedIn: true for 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-only with 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 as runtime.claude.ready.v1 or
    runtime.codex.ready.v1. For a runtime that is not signed in, a task start
    or continue fails with target 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 is refused with that reason instead
    of delivered. A probe that timed out or failed otherwise blocks no task;
    messages wait with retry-pending.

  • Control Plane: a task or intercom run without first turn progress 10
    minutes after its start is stopped and reported failed with no progress after start (issue #197). The messages a Claude intercom run carried are
    refused with target run made no progress after start; those of a Codex run
    get the wake-failed progress and are offered again within the offer limit.

  • Control Plane: msg status and msg send --wait show the sender states
    running and stopped, 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 status tool also returns senderState (running,
    stopped or the canonical state, from the same senderState function as
    msg status) and, for an accepted message without progress for 5 minutes,
    a fixed hint (issue #197). The state field is unchanged.

  • Control Plane: a Codex intercom run the node started on its own is listed
    with kind codex-intercom instead of codex-task, so the MCP sessions
    tool tells it apart from a requested task; msg sessions marks both as
    [background task] (issue #198).

  • Control Plane: an idle Claude Code session wakes after a restart without any
    user input (issue #101). A SessionStart input without permission_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
    permissionMode field, a regular file under projects/ of the Claude
    config directory; node/transcript-mode.mts) and stores it. A missing,
    foreign or unreadable transcript, or bypassPermissions there, 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 (audit backlog), 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 recorded auto or
    default mode (Claude Code claude --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 --new and the wake apply
    fail closed (kill switch, sessions and runtime, delegate.accept and the
    accept rules, reply depth, never bypassPermissions, maxConcurrent,
    workspace roots, the session's turn budget), a message causes one attempt
    at most, and every outcome is audited in wake.jsonl as closed-session
    resumed, new or refused with the reason. Every successful listing is
    kept for 7 days in known-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 (closedTo keeps 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 outcome resumed is replaced by
    reused (with the intercom session's taskId), next to new and
    refused.

  • Control Plane: the Claude Code wake listener is armed at SessionStart too
    (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
    SessionStart hooks with the same asyncRewake and timeout. A following
    prompt supersedes that listener as before. After compact the session
    counts as busy, because auto-compaction runs inside a turn. A SessionStart
    input carries no permission_mode, so the listener arms there only when,
    fail closed, the mode the session's last ...

Read more

Kherep 0.1.2

Choose a tag to compare

@cfaysal cfaysal released this 08 Oct 11:17

Added

  • A search verb 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 UserPromptSubmit hook asks for
    research on relevant prompts, naming the knowledge space and, inside a Git
    repository, the code graph. A Stop hook 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-only Stop group; the
    UserPromptSubmit Maestro context hook reminds the Maestro quietly to
    dispatch codex-obs once per main turn. Earlier managed Stop groups with an
    observation step are upgraded in place.

Kherep 0.1.1

Choose a tag to compare

@cfaysal cfaysal released this 08 Oct 11:17

Added

  • A commit policy file next to the commit-msg hook. The work-item rule now
    applies to every runtime that runs Git, not only to a process that carries
    the KHEREP_* variables. KHEREP_WORK_ITEM_REQUIRED and
    KHEREP_WORK_ITEM_PATTERN given at install time are persisted; a variable
    set at commit time still overrides the file.
  • labels --remove for 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.md and AGENTS.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_TOOLS now 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 an OBS-RESULT status 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

Choose a tag to compare

@cfaysal cfaysal released this 08 Oct 11:17

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-maestro plugin.
  • 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.