OXYGENHUB
◆ v0.4.1 oxygenhub / templates / help.html
11.1 KiB · HTML · last changed Wikis: Markdown pages as an Oxygen repository of their own 1 month ago source blame history raw
43e8ca33 Andy McCall ↶ 1
{% extends "base.html" %}
2
{% block title %}Help{% endblock %}
3
{% block content %}
4
<div class="head"><h1>Help <small>using {{ shell.site }}</small></h1></div>
5
<div class="sectioned help">
6
<nav class="section-nav" aria-label="Sections">
7
  <a href="#start">Getting started</a>
8
  <a href="#identity">Your identity</a>
9
  <a href="#push">Pushing</a>
10
  <a href="#clone">Cloning</a>
11
  <a href="#proposals">Proposals</a>
12
  <a href="#delegate">Letting the hub act for you</a>
13
  <a href="#flow">Pipelines</a>
14
  <a href="#keys">Keyboard</a>
15
  <a href="#glossary">Coming from GitHub</a>
16
</nav>
17
<div class="sections">
18
19
<section class="panel" id="start">
20
  <h2>Getting started</h2>
21
  <p>{{ shell.site }} hosts <strong>Oxygen</strong> repositories. You work with them through <code>oxy</code>, the Oxygen client; the hub shows them, reviews them and runs their pipelines. Every command below is filled in for this hub.</p>
22
  <ol>
23
    <li>Install <code>oxy</code>: build it from the <code>oxygen</code> repository with <code>cargo build --release</code> and put <code>target/release/oxy</code> on your path.</li>
24
    <li>Say who you are and make a signing identity (next section).</li>
25
    <li>{% if shell.user.is_some() %}Create a <a href="/settings/tokens">personal access token</a>{% else %}<a href="/register">Register</a>, then create a personal access token under Settings › Tokens{% endif %} with <code>repo:write</code>. It is shown once; keep it in <code>oxy</code>'s configuration, not in scripts.</li>
26
    <li>{% if shell.user.is_some() %}<a href="/new">Create a repository</a>{% else %}Create a repository with <strong>+ NEW</strong>{% endif %} and push to it (below). An empty repository shows the same commands, with its own address.</li>
27
  </ol>
28
  <p class="small mute"><code>oxy doctor</code> checks your identity, configuration and remotes, and says what to do about any problem.</p>
29
</section>
30
31
<section class="panel" id="identity">
32
  <h2>Your identity</h2>
33
  <p>Oxygen changes are signed. Your identity is a key pair (Ed25519 with ML-DSA-65) kept under <code>~/.config/oxy</code>; the public part travels with your changes.</p>
34
  {% let cmd = "oxy config --user author.name \"Your Name\"\noxy config --user author.email [email protected]\noxy identity create\noxy config --user core.sign change" %}
35
  <div class="cmds"><pre><code>{{ cmd }}</code></pre><button class="small" data-copy="{{ cmd }}">copy</button></div>
36
  <p>Link the key to your account under {% if shell.user.is_some() %}<a href="/settings/keys">Settings › Keys</a>{% else %}Settings › Keys{% endif %}: the page gives you a challenge to sign with <code>oxy identity sign-challenge</code>, which proves you hold the key. Linked keys show on your profile, and the hub can then tell which signed changes are yours.</p>
37
</section>
38
39
<section class="panel" id="push">
40
  <h2>Pushing</h2>
3e5cd2eb Andy McCall ↶ 41
  <p>From a checkout, add the repository as a remote, give it your token, and push{% if q.ca_url.is_some() %}. This hub's certificate is self-signed, so the commands also save it and point the remote at it{% endif %}:</p>
43e8ca33 Andy McCall ↶ 42
  {% let cmd = q.connect(self.repo_url().as_str()) %}
43
  <div class="cmds"><pre><code>{{ cmd }}</code></pre><button class="small" data-copy="{{ cmd }}">copy</button></div>
44
  <p>An empty repository takes its identity from the first push, so every later clone shares it. <code>oxy push {{ q.remote }}</code> sends the current bookmark; <code>oxy push {{ q.remote }} --bookmark NAME</code> another one. Tags travel with pushes.</p>
45
  <p class="small mute">A Git history comes across with <code>oxy git import --branch main path/to/git-checkout NAME</code>: every commit becomes a change, and the result can be pushed like any other repository.</p>
46
</section>
47
48
<section class="panel" id="clone">
49
  <h2>Cloning</h2>
50
  {% let cmd = self.clone_cmd() %}
51
  <div class="cmds"><pre><code>{{ cmd }}</code></pre><button class="small" data-copy="{{ cmd }}">copy</button></div>
52
  <p>Public repositories clone without a token. For private ones, and to push back, set <code>oxy config remote.origin.token YOUR-TOKEN</code>{% if q.ca_url.is_some() %} and <code>oxy config remote.origin.ca {{ q.ca_file }}</code>{% endif %} in the clone. <code>oxy pull origin</code> brings in what others pushed; there is no merge commit, because Oxygen changes combine by themselves.</p>
53
</section>
54
55
<section class="panel" id="proposals">
56
  <h2>Proposals</h2>
57
  <p>A proposal asks for a bookmark's changes to be added to another bookmark, like a pull request. Push your bookmark, then open one from the repository's Proposals tab, from the compare page's <strong>Propose this</strong>, or from a fork.</p>
58
  <ul>
59
    <li>A proposal is always tested and reviewed on its <strong>projected state</strong>: exactly what the target will hold once it lands. It never goes stale, and there is nothing to rebase.</li>
60
    <li>Review comments are anchored to lines' atoms, so they stay on the right line through later pushes.</li>
61
    <li>An approval can be a <strong>seal</strong>: your signature over the proposal's changes (<code>oxy seal</code>), which anyone can check offline.</li>
62
    <li>Land from the page, or from a client with <code>oxy proposal land URL</code>, which signs the landing with your own key.</li>
7d2eb590 Andy McCall ↶ 63
    <li>Where the site, an organisation or a repository has set up <strong>AI assistants</strong> (Settings), you can ask one to review under Reviewers, or have it draft the description; its answer is recorded as yours <em>via</em> the assistant, with an <span class="tag">agent</span> badge. Only people approve.</li>
43e8ca33 Andy McCall ↶ 64
  </ul>
65
</section>
66fd9d6b Andy McCall ↶ 66
<section class="panel" id="wiki">
67
  <h2>Wiki</h2>
68
  <p>A repository's wiki is Markdown pages kept as an Oxygen repository of their own: edit them under the <strong>Wiki</strong> tab (every edit is a signed change, so it needs the same delegation as editing code), or clone and push them as <code>oxy clone {{ shell.base_url }}/OWNER/NAME.wiki</code>. Pages are <code>Name.md</code> on <code>main</code>; <code>_Sidebar.md</code> is the sidebar; link between pages with <code>[Other](Other)</code>.</p>
69
</section>
43e8ca33 Andy McCall ↶ 70
71
<section class="panel" id="delegate">
72
  <h2>Letting the hub act for you</h2>
73
  <p>Edits in the browser and landings from the proposal page are changes too, and they must be signed. The hub signs them as your <strong>delegate</strong>, only if you allow it. Allowing it is a one-off step:</p>
74
  {% let cmd = self.delegate_cmd() %}
75
  <div class="cmds"><pre><code>{{ cmd }}</code></pre><button class="small" data-copy="{{ cmd }}">copy</button></div>
76
  <p>Then link your identity again under Settings › Keys, so the hub sees the delegation. You can withdraw it at any time with <code>oxy identity delegate remove</code>; a repository's trust policy still decides whether a delegated change may update a bookmark.</p>
77
</section>
78
79
<section class="panel" id="flow">
80
  <h2>Pipelines</h2>
81
  <p>Pipelines run in <strong>OxygenFlow</strong>. Put a pipeline in <code>.flow/pipeline.kdl</code> and push: each job runs in its own microVM with no network, and its result shows on the repository's Flow tab and as a check named <code>flow/JOB</code> on proposals. A site administrator enables Flow for a repository.</p>
82
  <p>Instead of a badge, a README can carry a <strong>state stamp</strong>:</p>
83
  {% let cmd = "[![flow](.flow/stamp)](.flow/run)" %}
84
  <div class="cmds"><pre><code>{{ cmd }}</code></pre><button class="small" data-copy="{{ cmd }}">copy</button></div>
85
  <p>It shows the result for the state you are looking at (a tag shows the tag's result), names that state, and carries each job's receipt hash.</p>
86
</section>
87
88
<section class="panel" id="keys">
89
  <h2>Keyboard</h2>
90
  <table class="list">
91
    <tbody>
92
      <tr><td><kbd>/</kbd></td><td>Search</td></tr>
93
      <tr><td><kbd>g</kbd> <kbd>c</kbd></td><td>The repository's code</td></tr>
94
      <tr><td><kbd>g</kbd> <kbd>h</kbd></td><td>History of the bookmark you are on</td></tr>
95
      <tr><td><kbd>g</kbd> <kbd>p</kbd></td><td>Proposals</td></tr>
96
      <tr><td><kbd>g</kbd> <kbd>i</kbd></td><td>Issues</td></tr>
97
      <tr><td><kbd>g</kbd> <kbd>b</kbd></td><td>Bookmarks</td></tr>
98
      <tr><td><kbd>g</kbd> <kbd>t</kbd></td><td>Trust</td></tr>
99
      <tr><td><kbd>y</kbd></td><td>Replace the address with a permalink to this exact state (files and trees)</td></tr>
100
      <tr><td>click a line number, <kbd>Shift</kbd>-click another</td><td>Select lines; copy them or a permalink to them</td></tr>
101
      <tr><td><kbd>?</kbd></td><td>The keyboard sheet</td></tr>
102
    </tbody>
103
  </table>
104
</section>
105
106
<section class="panel" id="glossary">
107
  <h2>Coming from GitHub</h2>
108
  <table class="list glossary">
109
    <thead><tr><th>GitHub</th><th>Here</th><th>What is different</th></tr></thead>
110
    <tbody>
111
      <tr><td>commit</td><td><strong>change</strong></td><td>A change records edits, not a snapshot, and names the changes it depends on. Changes that do not touch the same lines combine in any order with the same result, so there are no merge commits. A change keeps its identity when it is rebased or squashed.</td></tr>
112
      <tr><td>commit SHA, tree</td><td><strong>state</strong></td><td>The files a set of changes makes. A state is addressed by its heads (<code>a1b2…+c3d4…</code>); checks, stamps and permalinks belong to states.</td></tr>
113
      <tr><td>branch</td><td><strong>bookmark</strong></td><td>A name for a state. It can have several <strong>heads</strong> (changes nothing else depends on); the tree is their union, not a conflict.</td></tr>
114
      <tr><td>tag</td><td><strong>tag</strong></td><td>An immutable named state, usually signed.</td></tr>
115
      <tr><td>merge, rebase</td><td><code>oxy merge</code>, <code>oxy pull</code></td><td>Uniting bookmarks adds the other side's changes. Nothing is rewritten and no merge change is made.</td></tr>
116
      <tr><td>merge conflict</td><td><strong>conflict</strong> in the state</td><td>A conflict is recorded in the history instead of blocking you. It stays visible (the Conflicts tab) until a change resolves it, and anyone can resolve it later.</td></tr>
117
      <tr><td>pull request</td><td><strong>proposal</strong></td><td>Reviewed and tested on its projected state. It cannot go stale, and approvals can be signed seals.</td></tr>
118
      <tr><td>branch protection</td><td><strong>trust policy</strong></td><td>Signed rules in the repository itself: who may move which bookmark, with how many signatures. Every client enforces them, not only the hub.</td></tr>
119
      <tr><td>Actions, CI badge</td><td><strong>OxygenFlow</strong>, state stamp</td><td>Jobs run in microVMs on exact states; results are receipts, and the stamp says which state they belong to.</td></tr>
120
      <tr><td>git blame</td><td><strong>blame</strong></td><td>Exact through rebases and squashes: each line is an atom with one authoring change, so there is no "ignore revisions" file.</td></tr>
121
      <tr><td>fork</td><td><strong>fork</strong></td><td>A copy under your name with its own identity and bookmarks, sharing the stored objects. Its proposals go upstream as <code>you/name:bookmark</code>; the upstream's trust policy is not copied.</td></tr>
122
      <tr><td>personal access token</td><td><strong>token</strong></td><td>For pushing and the API. Your signing key is what proves authorship; a token only authorises.</td></tr>
123
    </tbody>
124
  </table>
125
</section>
126
127
</div>
128
</div>
129
{% endblock %}