AkurAI Build
Menu

Public repository / main

AkurAI-Build / app/pages/docs/index.html

Latest change 8d41f1e10aceed387d425b43038f2070e399a349 - OLI-277: schedules, reusable workflows (include + inputs), per-repository secrets (value or PassVault), native caches by Ólafur Búi Ólafsson

{% extends "layouts/docs.html" %}
{% block title %}Documentation — AkurAI Build{% endblock %}
{% block docs_title %}AkurAI Build documentation{% endblock %}
{% block docs_summary %}A practical guide to the Git, pipeline, artifact, and release contracts owned by the AkurAI Build control plane.{% endblock %}
{% block docs_content %}
<section id="overview">
  <h2>What AkurAI Build owns</h2>
  <p>AkurAI Build is a single Rust service for authenticated Git hosting and continuous delivery. One controller records repositories, immutable revisions, jobs, logs, artifacts, approvals, deployments, and worker state.</p>
  <ul class="ab-docs-checklist">
    <li><b>Git-native input.</b> Every run resolves an explicit ref to an immutable commit.</li>
    <li><b>Bounded execution.</b> Docker is the default executor; native jobs require an explicit trust decision.</li>
    <li><b>Persisted evidence.</b> Run state, logs, artifact digests, approvals, and deployments survive the browser session.</li>
    <li><b>Private by default.</b> Public repository visibility is an intentional owner action.</li>
  </ul>
</section>

<section id="quick-start">
  <h2>Quick start</h2>
  <ol>
    <li>Add a repository with <code>akurai_repo_add</code>, or mirror a trusted Titan checkout with <code>akurai_repo_host</code>.</li>
    <li>Commit a versioned <code>.akurai.yml</code> at the repository root.</li>
    <li>Queue a run with <code>akurai_run_queue</code> and inspect the persisted result with <code>akurai_run_show</code>.</li>
  </ol>
  <pre><code>version: 1
jobs:
  - name: test
    image: oven/bun:1.3
    network: true
    run:
      - bun install --frozen-lockfile
      - bun test

  - name: package
    needs: [test]
    image: oven/bun:1.3
    run: bun build src/index.ts --compile --outfile dist/app
    artifacts: [dist/**]</code></pre>
  <blockquote>Jobs depend on the previous job by default. Set <code>needs: []</code> only when a job is an independent root.</blockquote>
</section>

<section id="repositories">
  <h2>Repositories</h2>
  <p>Repository registration stores a stable name, Git URL, default branch, and visibility. Names are unique. Registration by URL keeps the upstream remote as the source; hosting creates an AkurAI Build-owned bare mirror from a trusted checkout.</p>
  <pre><code>akurai_repo_add
  name: payments-api
  url: https://git.example.com/team/payments-api.git
  branch: main</code></pre>
  <p>Hosted repositories clone from <code>https://akurai-build.olibuijr.com/git/&lt;name&gt;.git</code>. Authentication belongs in a credential helper—never in the URL. On the LAN they also clone over SSH with a key registered under <em>SSH keys</em>; every key is forced into <code>akurai git-shell</code>, which only runs git on hosted repositories with the same roles as HTTPS.</p>
  <p>Any repository you can read can be forked under a new name (you become its admin, and it can pull from its upstream later); forge admins can host mirrors of external Git URLs that refresh every ten minutes. <em>Search</em> finds code across every repository you may read through akurai-index, and each repository has an <em>Insights</em> tab with contributors, weekly activity and the most changed files.</p>
  <p>The repository workspace and each public repository provide stable ref/path links for trees, files, README content, and recent commits. Run history is server-paginated, filterable, shareable by URL, and links to canonical run detail pages.</p>
</section>

<section id="pipeline">
  <h2>Pipeline file</h2>
  <p>The repository-owned <code>.akurai.yml</code> is the complete execution contract. Jobs may declare dependencies, branches, matrix axes, caches, artifacts, environments, and approval requirements.</p>
  <div class="ab-docs-table-wrap">
    <table>
      <thead><tr><th>Field</th><th>Purpose</th></tr></thead>
      <tbody>
        <tr><td><code>needs</code></td><td>Names the jobs that must succeed first.</td></tr>
        <tr><td><code>branches</code></td><td>Restricts a job to explicit branch names.</td></tr>
        <tr><td><code>matrix</code></td><td>Expands bounded variants, including Linux architecture.</td></tr>
        <tr><td><code>artifacts</code></td><td>Retains matched output with digest and size evidence.</td></tr>
        <tr><td><code>environment</code></td><td>Associates a deployment with a protected target.</td></tr>
        <tr><td><code>approval</code></td><td>Stops promotion until an operator approves it.</td></tr>
      </tbody>
    </table>
  </div>
</section>

<section id="execution">
  <p>Pipelines can also declare <code>schedules</code> (five-field cron, UTC, read from the default branch and queued once per matching minute), reuse job lists with <code>include</code> (a <code>version: 1</code> file with <code>jobs</code>, from this repository or another hosted one, parameterised with <code>$&#123;&#123; inputs.NAME &#125;&#125;</code> and <code>with</code>), and declare <code>secrets</code> that resolve from the repository's own secrets (stored values or PassVault entries, managed by admins under <code>/api/repos/&lt;name&gt;/secrets</code>) before the worker's <code>AKURAI_SECRET_*</code> environment. <code>cache</code> paths work for native jobs too.</p>

  <h2>Job execution</h2>
  <h3>Docker jobs</h3>
  <p>Docker jobs run with dropped capabilities, <code>no-new-privileges</code>, bounded CPU, memory, and process counts, a read-only root filesystem, and no network unless <code>network: true</code> is declared.</p>
  <h3>Native jobs</h3>
  <p>Native execution is for trusted repositories only and requires the controller's production opt-in. Repository writers can execute pipeline code, so native access and secret-bearing jobs are privileged operations.</p>
</section>

<section id="artifacts">
  <h2>Artifacts</h2>
  <p>Artifact records belong to an immutable run and job. AkurAI Build stores the relative path, SHA-256 digest, byte size, and retained file location. Promotion uses recorded outputs from successful dependency jobs rather than rebuilding unknown bytes.</p>
</section>

<section id="mcp">
  <h2>MCP workflow</h2>
  <p>Agents and operators use the configured AkurAI Build MCP tools for control-plane state. Each response is structured JSON; queued or running work is incomplete until a persisted terminal state is observed.</p>
  <pre><code>akurai_repo_list     # discover repositories
akurai_repo_branches # inspect remote refs
akurai_run_queue     # pin and queue a revision
akurai_run_wait      # wait for terminal or approval-required state
akurai_run_show      # inspect jobs, artifacts, and deployments
akurai_run_logs      # read bounded retained logs
akurai_run_promote   # approve one protected environment</code></pre>
</section>

<section id="releases">
  <h2>Protected releases</h2>
  <p>A protected deployment waits after its dependency jobs succeed. Approval resumes only the named environment on that immutable run. A successful release requires persisted success, a healthy service, and revision confirmation; queued, running, or waiting states are not completion.</p>
</section>

<section id="security">
  <h2>Security model</h2>
  <ul>
    <li>SQLCipher state and secrets remain outside repositories and retained logs.</li>
    <li>API and Git requests use bounded bodies, timeouts, and constant-time credential checks.</li>
    <li>Browser mutations require an authenticated session and same-origin request.</li>
    <li>Paths, refs, artifact names, and repository names are validated before reaching Git or the filesystem.</li>
    <li>Secrets are exact-value redacted from retained job logs.</li>
  </ul>
  <blockquote>Repository writers are privileged. Pipeline commands are code, and code can intentionally transform or disclose any secret it receives.</blockquote>
</section>

<nav class="ab-docs-pagination" aria-label="Documentation completion">
  <a href="/">Back to homepage</a>
  <a href="/login">Open your workspace <span aria-hidden="true">→</span></a>
</nav>
{% endblock %}