# Keep the index current with Git and GitHub

Indexing once gives you a map of that moment. Hooks keep it useful after the code changes. Start with the local Git hook; add CI only when you have a host and credentials designed for it.

## 1. Install the local post-commit hook {#local}

From the repository you want to maintain:

```
korium-cli hooks install
```

The CLI uses Git’s configured hooks directory, including `core.hooksPath`. It will not overwrite a hook it did not create. If another tool, such as husky or lefthook, owns post-commit, install prints the lines to add at the end of that tool’s hook; review them and merge them with that tool’s owner. The lines start with a comment the CLI recognizes, so the next install says the hook already runs them instead of printing them again.

If `core.hooksPath` comes from your global git configuration rather than the repository’s, every repository on the Mac that does not set its own shares that folder, and so shares the hooks installed there. Install says so when it happens.

The installed hook runs `korium-cli index --allow-removals --no-wait --from-hook` after an ordinary commit. It updates the index of the branch the commit was made on. It permits intentional symbol removals and returns after upload acceptance, without holding the commit open while the server publishes the index.

The hook never holds a commit for a sign-in. If this Mac is not signed in, it opens the Korium sign-in in your browser in the background and the commit finishes at once; the index is updated when you finish signing in. While that sign-in is open, later commits do not open another. If you decline, or do not finish in time, hooks do not open the sign-in again for an hour, or until you run a korium-cli command yourself; until then each one prints a line saying the index was not updated and to run `korium-cli login`. On a Mac session that cannot open a browser, such as an ssh login, the hook prints that same line. A hook installed by an earlier korium-cli behaves the same way.

You may not need to type `hooks install` at all. When you index a repository from a terminal and it has no Korium hook, korium-cli asks once: “Keep this repository’s index current automatically? [y/N]”. Yes does exactly what `korium-cli hooks install` does. No, or Enter, is remembered for that repository, and `korium-cli hooks install` still works whenever you change your mind. The same question follows `korium-cli login` when you run it inside a repository. A hook, a pipe, CI or an agent is never asked, and a repository whose hooks you removed with `hooks uninstall` is not asked again.

### Delete a branch’s index when you delete the branch {#branch-deletes}

```
korium-cli hooks install --branch-deletes
```

This also installs a reference-transaction hook, so `git branch -d` or `-D` on a local branch deletes Korium’s index of that branch. It is opt-in because a branch’s index belongs to the whole workspace, not to one checkout. Renaming a branch with `git branch -m` never deletes an index; the index under the old name stays, and unless it is the trunk, Korium removes it once nobody has indexed that name for 14 days. The hook never deletes the trunk or a repository’s last index: Korium refuses those without `--allow-removals`, and the hook never sends it. The hook works in the background, so `git branch -d` never waits on Korium. What it did, refusals included, is written to `~/.local/state/korium-cli/branch-deletes.log` rather than printed. A post-commit hook owned by another tool does not stop this one from being installed.

To delete a branch’s index yourself, run `korium-cli delete BRANCH` from the repository. It deletes Korium’s index and leaves your git branch alone.

## Know what that hook does not cover {#limits}

A merge does not run Git’s post-commit hook. Replayed commits during operations such as rebase, cherry-pick and revert are deliberately skipped by Korium’s hook. Run `korium-cli index` after the operation settles, or let the next ordinary commit do it.

A post-commit failure does not undo the commit. The commit may be fine while the search index is still stale. A successful no-wait run is also not a publication check.

The Git hook sees only commits. An agent edits between commits, so `korium-cli hooks install` also prints an end-of-task hook for Claude Code, described in the [Claude Code guide](claude-code.html#hooks); Codex has its own [task-end example](codex.html#publishing-branch). Each hook updates only the index of the branch it runs on. When a second one runs and no file has changed since the first, it finds nothing to send.

Use the [setup checklist](release-status.html) to verify transcript sources, memory connections and your branch code indexes before automating the work.

## Remove the hook safely {#remove}

```
korium-cli hooks uninstall
```

The CLI removes only the hooks it recognizes as its own, the branch-delete hook included. To remove only the branch-delete hook and keep the post-commit hook, run `korium-cli hooks uninstall --branch-deletes`. If you manually incorporated its lines into another hook manager, remove that entry through the same manager instead; uninstall leaves that file alone and says so. Don’t delete somebody else’s post-commit file.

## 2. Prepare a self-hosted Mac for GitHub Actions {#github}

The current CLI is a macOS application with a local keychain sign-in. This example uses a dedicated, self-hosted Mac, not an ephemeral GitHub-hosted runner. Use a private, trusted repository and a runner group restricted to the intended repository.

Install the CLI and complete login under the same operating-system account that runs the runner. Verify `/usr/local/bin/korium-cli status` in the runner’s actual execution context. If it cannot access its sign-in there, stop and fix that host setup; don’t export credentials into GitHub secrets.

Label the runner `korium` after those checks. Protect changes to workflows and the default branch. Do not allow untrusted pull requests to execute on a machine holding Korium credentials. GitHub explains the risk in its [self-hosted runner security guidance](https://docs.github.com/en/actions/reference/security/secure-use).

## 3. Start with a manual, reviewed run {#workflow}

Save this as `.github/workflows/korium-index.yml`. It indexes the repository’s default branch, which is normally its trunk: the index a search reads when it names no branch. It runs only when a permitted person dispatches it on the default branch; it does not run pull-request code.

```
name: Index the reviewed default branch
on:
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: korium-code-index
  cancel-in-progress: false

jobs:
  index:
    if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
    runs-on: [self-hosted, macOS, korium]
    timeout-minutes: 45
    steps:
      - name: Check out the reviewed commit
        # Pinned checkout v4.2.2. Review updates under your team's policy.
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
        with:
          ref: ${{ github.event.repository.default_branch }}
          fetch-depth: 0
          persist-credentials: false
      - name: Verify the publishing checkout
        env:
          KORIUM_EXPECTED_BRANCH: ${{ github.event.repository.default_branch }}
        shell: bash
        run: |
          set -euo pipefail
          korium_branch=$(git symbolic-ref --quiet --short HEAD)
          test "$korium_branch" = "$KORIUM_EXPECTED_BRANCH"
          test -z "$(git status --porcelain --untracked-files=normal)"
      - name: Check the runner's Korium connection
        run: /usr/local/bin/korium-cli status
      - name: Build and publish the code map
        run: /usr/local/bin/korium-cli index --allow-removals

```

The full fetch preserves repository history for the root-based identity. The explicit ref and branch check avoid silently publishing from a detached or different checkout. The pinned action is a reviewed example version, not a claim that it is the newest release.

If the runner’s checkout does not record which branch the remote calls its default, korium-cli says so and does not tell Korium which branch is the trunk. Korium then keeps the trunk it has, or, for a repository with none, takes this first index as the trunk.

The CLI makes a bounded publication check here. A green job does not, by itself, prove the new commit answers searches. Complete the verification below before reporting it ready.

Before allowing an automatic trigger, prove the manual run works and decide who can update the default branch’s index. Don’t add `pull_request_target` or check out an untrusted PR head on this authenticated machine.

## 4. Verify the result, not just the green job {#verify}

Read the job’s final publication output, then search for a known symbol at the commit that was checked out. Confirm the returned commit and open the corresponding source span. Even without `--no-wait`, a zero CLI exit can leave publication unverified.

For a structured check, call `code_locate` with the repository identity and actual checkout SHA. Inspect the returned index commit, freshness information and symbol location. Do not parse a progress sentence as a stable machine API.

This workflow updates the code map. It does not copy issues, pull requests or review decisions into company memory. If you build that separate integration, give it explicit access and record the source links, author and review status of what it captures.
