diff options
| author | WebX11 SysOp <darkmotox11@gmail.com> | 2026-11-05 22:26:25 +0100 |
|---|---|---|
| committer | WebX11 SysOp <darkmotox11@gmail.com> | 2026-11-05 22:26:25 +0100 |
| commit | 2efbcea4785402134c4db09d3febda0e82aab71e (patch) | |
| tree | 23b58bb76090bba34a88f46ab841cd64425d124c | |
| parent | 4f279d975c8aa55f44934a2ab6af67ebd3f7d454 (diff) | |
feat(git): contrib push surface with automated moderation
Users push to push.newos.webx11.duckdns.org with a per-user token; the read-only
host is untouched. http.receivepack is unset so git only allows receive-pack when
REMOTE_USER is present, which only that vhost sets. A pre-receive hook (installed
by the publisher every run) allows refs/heads/contrib/* only and refuses banned
paths, credential-shaped blobs, >200 files or >2MB, logging user+ref+decision.
moderate-contrib.py triages every 10 min: deletes hard violations, stamps the
rest ready-docs/review/stale into a queue rendered at /admin/git-contrib.html.
A human still decides what merges.
Verified end to end: contrib push accepted, main refused, credential file
refused, accepted ref visible on the read-only host; guard extended (push host
401, hook present+executable, receivepack unset) and proven RED by removing the
hook.
| -rw-r--r-- | docs/usage.html | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/docs/usage.html b/docs/usage.html index 4fbb7cb..017f6e4 100644 --- a/docs/usage.html +++ b/docs/usage.html @@ -286,6 +286,42 @@ pi -p --no-session --no-tools --mode json --model gemma4:31b-cloud \ <p style="color:var(--dim);font-size:.9rem">The mirror only fast-forwards, so <code>git pull --ff-only</code> can never wedge. Nothing here can push — the repository refuses <code>receive-pack</code> at three levels.</p> +<h2 id="contributing">Contributing (contrib branches)</h2> +<p>The mirror accepts contributions, but only as <strong>contrib branches</strong> — <code>main</code> is +generated from the platform's monorepo and a push to it would be erased by the next publish. Pushes go to +a separate host that asks for credentials; the read-only host in your <code>origin</code> stays anonymous +and read-only.</p> +<pre><code># 1. one token per account, issued by the platform operator +# (looks like: https://<user>:wx11gp_…@push.newos.webx11.duckdns.org/newos4.git) +git remote add push https://push.newos.webx11.duckdns.org/newos4.git + +# 2. work on a branch, push it under contrib/ +git switch -c contrib/my-fix +git commit -am "fix(shell): handle an empty command" +git push push HEAD:refs/heads/contrib/my-fix</code></pre> +<p style="color:var(--dim);font-size:.9rem">Use a credential helper rather than pasting the token into the +URL of a repository you might publish. Git will ask once and can remember it +(<code>git config --global credential.helper store</code> writes it to a plain file — choose +<code>cache</code> or your OS keychain if that matters).</p> + +<h3>What the server enforces</h3> +<table> + <tr><th>Rule</th><th>Reason</th></tr> + <tr><td>Only <code>refs/heads/contrib/*</code></td><td><code>main</code> and tags are generated by the publisher; a push there would disappear at the next publish</td></tr> + <tr><td>No credentials in the diff</td><td>The repository is public. Every added blob is scanned before it is accepted; a match rejects the whole push with the file name</td></tr> + <tr><td>No profile or key files</td><td><code>.user.json</code>, <code>.session</code>, <code>.env</code>, <code>*.pem</code>, <code>id_rsa</code> are refused by path</td></tr> + <tr><td>≤ 200 files, ≤ 2 MB of new content per push</td><td>Keeps one push from making the mirror unusable</td></tr> + <tr><td>Deleting your own contrib branch</td><td>Allowed — it is your branch</td></tr> +</table> + +<h3>What happens after you push</h3> +<p>A moderator triages every branch automatically: docs-only changes are marked <em>ready</em>, anything +touching code is queued for a human with a diff summary, and a branch that breaks a hard rule is deleted. +The queue is visible to the operator; you will hear back on your branch, not in a black hole.</p> +<pre><code>git fetch push 'refs/heads/contrib/*:refs/remotes/contrib/*' +git log --oneline main..contrib/my-fix # what your branch adds +git push push --delete contrib/my-fix # withdraw it</code></pre> + <h2 id="updating">Updating later</h2> <pre><code>cd newos4 git pull --ff-only # the mirror only ever fast-forwards |