HivemindOS manual

AEON GitHub Actions Brain Access

Let AEON runs on GitHub Actions read approved parts of your brain. The runner joins your tailnet for the length of the job and calls one policy-checked endpoint on any online HivemindOS machine:

POST /api/runtimes/aeon/brain

The runner never gets file access to your vault and never becomes a sync peer.

What each repository can reach

The endpoint checks the job’s GitHub identity token, looks up the repository’s visibility on GitHub, and applies a policy:

Repository Access
Public, or visibility cannot be confirmed Restricted search and read, plus limited append
Private Full list, read, search, append, and bulk export
Internal Full by default; you can change this in the policy

Restricted access always excludes private paths such as:

PRIVATE/**
People/Private/**
Operations/Secrets/**
**/secrets/**
.obsidian/**
.trash/**
**/.env*
**/*.gpg

To change the defaults, create <vault>/.hivemindos/aeon-brain-policy.json:

{
  "visibility": {
    "public": {
      "maxResults": 20,
      "exclude": ["PRIVATE/**", "People/Private/**", "Finance/**"]
    }
  },
  "repos": {
    "<owner>/specific-public-repo": {
      "mode": "unrestricted",
      "allowedActions": ["policy", "search", "read", "list", "append", "bulk"],
      "allowNoteOpen": true,
      "allowDirectoryListing": true,
      "allowBulkExport": true,
      "include": ["**"],
      "exclude": [],
      "appendAllow": ["**"]
    }
  }
}

To check private repositories, each HivemindOS machine needs a GitHub token in GITHUB_TOKEN, GH_TOKEN, or GH_GLOBAL. It is used only to read repository visibility. Connecting GitHub in HivemindOS can provide GH_GLOBAL for you.

Set up your tailnet

Tag the HivemindOS machines that serve the endpoint tag:hivemind-brain, and let runners join as tag:aeon-ci. Allow only the endpoint’s port between them:

{
  "tagOwners": {
    "tag:aeon-ci": [],
    "tag:hivemind-brain": ["autogroup:admin"]
  },
  "grants": [
    {
      "src": ["tag:aeon-ci"],
      "dst": ["tag:hivemind-brain"],
      "ip": ["tcp:443"]
    }
  ]
}

Add the workflow step

The job gets a GitHub identity token, joins the tailnet as tag:aeon-ci, and calls the endpoint:

permissions:
  contents: read
  id-token: write

jobs:
  aeon:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - name: Join HivemindOS tailnet
        uses: tailscale/github-action@v4
        with:
          oauth-client-id: $
          audience: $
          tags: tag:aeon-ci
          ping: $

      - name: Pull scoped brain context
        run: |
          token="$(curl -fsSL "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${HIVE_AEON_BRAIN_OIDC_AUDIENCE}" \
            -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" | jq -r .value)"
          curl -fsSL "https://${HIVE_BRAIN_HOST}/api/runtimes/aeon/brain" \
            -H "Authorization: Bearer ${token}" \
            -H "content-type: application/json" \
            -d '{"action":"search","query":"repo context and prior decisions"}'
        env:
          HIVE_BRAIN_HOST: $
          HIVE_AEON_BRAIN_OIDC_AUDIENCE: $

Set the same HIVE_AEON_BRAIN_OIDC_AUDIENCE on every HivemindOS machine that serves the endpoint. If it is not set, the endpoint expects hivemindos-aeon-brain.

Report finished runs

A workflow can also report its result, so the automation’s row in the Automations view updates as soon as the run ends:

POST /api/runtimes/aeon/runs/report

It uses the same token and checks as the brain endpoint. Only finished runs are accepted (status of ok/success or failed/failure). Reporting the same run twice never duplicates history.

      - name: Report the finished run
        if: always()
        run: |
          token="$(curl -fsSL "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${HIVE_AEON_BRAIN_OIDC_AUDIENCE}" \
            -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" | jq -r .value)"
          curl -fsSL "https://${HIVE_BRAIN_HOST}/api/runtimes/aeon/runs/report" \
            -H "Authorization: Bearer ${token}" \
            -H "content-type: application/json" \
            -d "{\"skill\":\"${AEON_SKILL}\",\"status\":\"$\",\"summary\":\"$(cat output/summary.txt 2>/dev/null | head -c 1500)\",\"url\":\"$/$/actions/runs/$\"}"

The report is matched to an automation by skill name and records the result, summary, and run-log link. If the skill is not saved as an automation in the Automations view yet, the report comes back as not found.

Expanded image Scroll to pan · Esc to close
100%