<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Taskweft — Manuals</title>
<link>https://weftspun.github.io/request-for-discussion/pages/rfd.html</link>
<atom:link href="https://weftspun.github.io/request-for-discussion/pages/rfd.xml" rel="self" type="application/rss+xml"/>
<description>Request-for-Discussion documents, the serial register, and the logbook.</description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Tue, 01 Sep 2026 01:25:01 GMT</lastBuildDate>
<item>
  <title>RFD 2142: Zero-trust service TLS via OpenBao PKI</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2142-bao-pki-zerotrust-service-tls/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Services on 6PN read secrets from bao over plaintext HTTP. The root token in 1Password is for emergencies; sharing it with services is the credential distribution problem bao exists to solve. Any 6PN neighbor can observe or modify traffic to the listener.</p>
<p>The FDB root CA key is lost a second time (the replacement from RFD 2141 was stored via <code>op item create</code>, which returned an item ID but did not persist the item). Chaining under that CA is not possible without rotating FDB again.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Bao’s PKI secrets engine becomes a standalone root CA for service auth. The FDB CA (<code>fdb-ca.chibifire.com</code>) stays separate for cluster mutual TLS.</p>
<ol type="1">
<li>Mount <code>pki/</code> and generate a root CA inside bao.</li>
<li>Issue a listener cert; enable TLS on <code>:8200</code>.</li>
<li>Enable the TLS cert auth backend. Each service presents a client cert signed by bao’s PKI and receives a scoped token for its KV paths.</li>
<li>Elixir services use <code>libvault</code> (hex.pm) as the vault client.</li>
</ol>
<p><strong>Gate:</strong> bao rejects a plaintext request to <code>:8200</code>. <strong>Negative control:</strong> a request with no client cert, or with an expired cert, returns 403.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 2140 (bao on FDB), RFD 2141 (FDB TLS rotation).</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2142-bao-pki-zerotrust-service-tls/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2142-bao-pki-zerotrust-service-tls/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2141: FDB TLS rotation without data loss</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2141-fdb-tls-rotation-without-data-loss/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The CA private key from RFD 2134 is not recoverable, so no new leaf can be issued. bao needs a client cert, and the machine certs expire in two years. RFD 2134’s reset path wipes data, which was acceptable at initial setup and is not acceptable now.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>A three-phase rolling rotation using FDB’s automatic TLS certificate refresh. The cluster stays available and data stays intact at every step; each phase is gated on <code>fdbcli status</code> reporting healthy.</p>
<p><strong>Phase 1 (dual-CA trust).</strong> Generate a new CA with the RFD 2134 profile. Set <code>FDB_TLS_CA_B64</code> to old + new CAs concatenated. Rolling restart. Every machine trusts certs from either CA.</p>
<p><strong>Phase 2 (new leaves).</strong> Mint new certs under the new CA for all three machines and for bao (<code>fdb-bao.chibifire.com</code>). Replace each machine’s cert/key secrets. Rolling restart.</p>
<p><strong>Phase 3 (drop old CA).</strong> Set <code>FDB_TLS_CA_B64</code> to the new CA only. Rolling restart. Store the new CA key in bao and in 1Password.</p>
<p>The cluster file does not change (addresses keep <code>:tls</code>), so no coordinator reset is needed.</p>
<p>The rotation tool is an Elixir TUI in weft-warp-burrito, packaged via Burrito. It walks the phases, gates each on cluster health, and stores the CA key on completion. The procedure is in DETAILS.md.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 2134 (initial TLS), RFD 2140 (OpenBao on FDB).</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2141-fdb-tls-rotation-without-data-loss/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2141-fdb-tls-rotation-without-data-loss/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2140: OpenBao on FoundationDB</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2140-openbao-on-foundationdb/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>OpenBao dropped every storage plugin when it forked from Vault v1.14.x. The weftspun-fdb cluster already runs three machines with double redundancy, TLS, and backup, and raft on a single shared-cpu machine has no replication path.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Restore the FoundationDB backend from Vault v1.14.8 (last MPL-2.0 release), connecting to the existing weftspun-fdb cluster over 6PN. The port rewrites three interfaces that diverged after the fork: <code>ListPage</code>, interactive transactions (<code>BeginTx</code>/<code>BeginReadOnlyTx</code> with Commit/Rollback), and pins the FDB 7.3.79 Go binding (<code>headerVersion = 730</code>). Build tag <code>foundationdb</code>, <code>CGO_ENABLED=1</code>.</p>
<p>Deployment files in weftspun/service-openbao. The bao machine carries only the FDB client library and connects to the cluster via a TLS client certificate. Interface details and deploy measurements are in DETAILS.md.</p>
</section>
<section id="verification" class="level2">
<h2 class="anchored" data-anchor-id="verification">Verification</h2>
<p><code>bao status</code>: Storage foundationdb, unsealed. KV v2 at <code>secret/</code>, anchor creds written from weftspun-fdb over 6PN. Root in 1Password.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 2109 (FDB as the store), RFD 2134 (cluster TLS).</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2140-openbao-on-foundationdb/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2140-openbao-on-foundationdb/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2139: MaskScore QAFT and extraction budget</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2139-maskscore-qaft-budget/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The MaskScore extraction pipeline (RFD 1173) needs seven models co-resident on GPU. At published precision (bf16), VoxHammer alone requires 40 GB. QAFT to NF4 is required before extraction can begin. Condition 5 permits this: QAFT makes NF4 the published precision.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>QAFT all seven pipeline models to NF4. Fork each upstream model on HF.</p>
<section id="architecture-forked-base-with-qaft-checkpoint" class="level3">
<h3 class="anchored" data-anchor-id="architecture-forked-base-with-qaft-checkpoint">Architecture: forked base with QAFT checkpoint</h3>
<p>Each upstream model is forked to chibifire/ on HF. The fork stores:</p>
<ol type="1">
<li>the original bf16 weights (upstream copy, for provenance)</li>
<li>the QAFT’d NF4 checkpoint (merged, the working base)</li>
<li>future adaptations as LoRAs on the NF4 base</li>
</ol>
<p>QAFT produces a merged NF4 checkpoint, not a LoRA. The NF4 checkpoint is the new base. Only post-QAFT work (RL, domain adaptation) is stored as LoRA adapters against it.</p>
</section>
<section id="models-to-qaft" class="level3">
<h3 class="anchored" data-anchor-id="models-to-qaft">Models to QAFT</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 32%">
<col style="width: 8%">
<col style="width: 9%">
<col style="width: 11%">
<col style="width: 14%">
<col style="width: 23%">
</colgroup>
<thead>
<tr class="header">
<th>model</th>
<th>params</th>
<th>bf16</th>
<th>NF4 est.</th>
<th>where</th>
<th>HF fork</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Qwen3-Omni thinker (30B MoE)</td>
<td>~30B</td>
<td>~30 GB</td>
<td>~9.3 GB</td>
<td>Vast.ai A100</td>
<td>chibifire/qwen3-omni</td>
</tr>
<tr class="even">
<td>Qwen3-Omni talker</td>
<td>~10B</td>
<td>~10 GB</td>
<td>~2.5 GB</td>
<td>Vast.ai A100</td>
<td>(same repo)</td>
</tr>
<tr class="odd">
<td>Wan-VACE</td>
<td>~14B</td>
<td>~28 GB</td>
<td>~8.7 GB</td>
<td>Vast.ai A100</td>
<td>chibifire/wan-vace</td>
</tr>
<tr class="even">
<td>Pixal3D (8 subs)</td>
<td>~4B</td>
<td>~8 GB</td>
<td>~2.5 GB</td>
<td>Vast.ai A100</td>
<td>chibifire/pixal3d</td>
</tr>
<tr class="odd">
<td>VoxHammer</td>
<td>TBD</td>
<td>40 GB+</td>
<td>TBD</td>
<td>Vast.ai A100</td>
<td>chibifire/voxhammer</td>
</tr>
<tr class="even">
<td>MoGe-3 (ViT-L)</td>
<td>~300M</td>
<td>~600 MB</td>
<td>~190 MB</td>
<td>local Mac</td>
<td>chibifire/moge3</td>
</tr>
<tr class="odd">
<td>ANNY inverter</td>
<td>small</td>
<td>small</td>
<td>skip</td>
<td>n/a</td>
<td>n/a</td>
</tr>
</tbody>
</table>
<p>ANNY is a small vertex correspondence fitter; Mitsuba 3 is a physics-based renderer. Neither needs QAFT.</p>
</section>
<section id="extraction-ladder-galls-law" class="level3">
<h3 class="anchored" data-anchor-id="extraction-ladder-galls-law">Extraction ladder (Gall’s Law)</h3>
<p>Each rung proves the next is worth building.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 5%">
<col style="width: 7%">
<col style="width: 7%">
<col style="width: 17%">
<col style="width: 11%">
<col style="width: 10%">
<col style="width: 37%">
</colgroup>
<thead>
<tr class="header">
<th>rung</th>
<th>trials</th>
<th>rows</th>
<th>GPUs</th>
<th>est. hours</th>
<th>est. cost</th>
<th>proves</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>-1</td>
<td>0</td>
<td>0</td>
<td>1x A100 80GB</td>
<td>~8</td>
<td>~$12</td>
<td>QAFT all models to NF4</td>
</tr>
<tr class="even">
<td>0</td>
<td>1</td>
<td>8</td>
<td>1x A100</td>
<td>minutes</td>
<td>~$0.03</td>
<td>extraction script runs, 8 stubs emit</td>
</tr>
<tr class="odd">
<td>1</td>
<td>13</td>
<td>~104</td>
<td>same</td>
<td>~15 min</td>
<td>~$0.38</td>
<td>all 13 task types construct</td>
</tr>
<tr class="even">
<td>2</td>
<td>130</td>
<td>~1040</td>
<td>same</td>
<td>~2 hr</td>
<td>~$3</td>
<td>scoring separates good from bad</td>
</tr>
<tr class="odd">
<td>3</td>
<td>390</td>
<td>~3120</td>
<td>same</td>
<td>~6 hr</td>
<td>~$9</td>
<td>usable bench set</td>
</tr>
<tr class="even">
<td>4</td>
<td>12k</td>
<td>~97k</td>
<td>9x RTX 3090</td>
<td>~8 hr</td>
<td>~$14</td>
<td>reward-train complete</td>
</tr>
<tr class="odd">
<td>5</td>
<td>14k</td>
<td>~210k</td>
<td>18x RTX 3090</td>
<td>~8 hr</td>
<td>~$29</td>
<td>all three datasets complete</td>
</tr>
</tbody>
</table>
</section>
<section id="cost-summary" class="level3">
<h3 class="anchored" data-anchor-id="cost-summary">Cost summary</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>line item</th>
<th>cost</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>QAFT all models to NF4 (rung -1)</td>
<td>~$12</td>
</tr>
<tr class="even">
<td>MoGe-3 QAFT</td>
<td>$0 (local Mac)</td>
</tr>
<tr class="odd">
<td>Rungs 0 through 3 (same A100 session)</td>
<td>~$13</td>
</tr>
<tr class="even">
<td>Rung 4 (9x RTX 3090 spot, 8 hr)</td>
<td>~$14</td>
</tr>
<tr class="odd">
<td>Rung 5 (18x RTX 3090 spot, 8 hr)</td>
<td>~$29</td>
</tr>
<tr class="even">
<td><strong>Total</strong></td>
<td><strong>~$68</strong></td>
</tr>
</tbody>
</table>
</section>
<section id="vast.ai-tear-down-discipline" class="level3">
<h3 class="anchored" data-anchor-id="vast.ai-tear-down-discipline">Vast.ai tear-down discipline</h3>
<p>Per the working agreements: commit and push before tear down, then double-check the tear down. The extraction script pushes parquet to HF after each batch, so a torn-down machine loses at most one batch, not the full run.</p>
</section>
<section id="hf-artifacts" class="level3">
<h3 class="anchored" data-anchor-id="hf-artifacts">HF artifacts</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 45%">
<col style="width: 12%">
<col style="width: 42%">
</colgroup>
<thead>
<tr class="header">
<th>artifact</th>
<th>type</th>
<th>purpose</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>chibifire/qwen3-omni</td>
<td>model</td>
<td>bf16 + QAFT NF4 base</td>
</tr>
<tr class="even">
<td>chibifire/wan-vace</td>
<td>model</td>
<td>bf16 + QAFT NF4 base</td>
</tr>
<tr class="odd">
<td>chibifire/pixal3d</td>
<td>model</td>
<td>bf16 + QAFT NF4 base</td>
</tr>
<tr class="even">
<td>chibifire/voxhammer</td>
<td>model</td>
<td>bf16 + QAFT NF4 base</td>
</tr>
<tr class="odd">
<td>chibifire/moge3</td>
<td>model</td>
<td>bf16 + QAFT NF4 base</td>
</tr>
<tr class="even">
<td>chibifire/maskscore-bench</td>
<td>dataset</td>
<td>evaluation (~2890 rows)</td>
</tr>
<tr class="odd">
<td>chibifire/maskscore-reward-train</td>
<td>dataset</td>
<td>reward model training (~97k)</td>
</tr>
<tr class="even">
<td>chibifire/maskscore-rl-train</td>
<td>dataset</td>
<td>RL training (~110k)</td>
</tr>
</tbody>
</table>
</section>
<section id="what-is-not-in-this-budget" class="level3">
<h3 class="anchored" data-anchor-id="what-is-not-in-this-budget">What is NOT in this budget</h3>
<ul>
<li>SpeakingFaces download (already on local compute)</li>
<li>The reward model training itself (rung 5 produces data, not a model)</li>
</ul>
</section>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1173 (the pipeline design), RFD 1143 (keypoints to ANNY).</p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2139-maskscore-qaft-budget/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2138: interactor-shuttle merges spot-broker and uro</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2138-interactor-shuttle-merges-spot-broker-and-uro/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>uro held V-Sekai users and served content; spot-broker held the vast.ai key and posted double-entry entries for spend. Both needed GitHub sign-in, both wanted the same TigerBeetle-shaped ledger, and neither could hand a stranger a downloadable VRM without the other: two GitHub OAuth apps, two Fly apps, two deploy pipelines, one user story.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>They merge as <strong>interactor-shuttle</strong> at <code>3-interactor/interactor-shuttle</code>. Interactor because the primary role is user-facing (GitHub sign-in, landing page, roll button, VRM download); spot-broker’s keeper policy, the TigerBeetle accounting on ecto_sqlite3, and the FoundationDB event ledger become internal modules rather than peers. <code>shuttle</code> fits the weaving vocabulary the workspace already uses (weftspun, sinew, taskweft). spot-broker’s Fly URL and repo become redirects; RFDs 2133-2137 stay as written, naming the predecessor service, per the retractions-stay-in-place rule.</p>
<p>Migrating unchanged: one holder of the vast.ai key (the shuttle process); keeper singleton-with-hysteresis (RFD 2133); mutual-TLS FoundationDB cluster plus Tigris backup (RFDs 2134-2135); TigerBeetle-shaped Account and Transfer tables, sum-to-zero by construction; GitHub OAuth via oauth_mcp_bridge with a <strong>new</strong> SH_GH_* credential set, so spot-broker’s SB_GH_* credentials rotate out with the rename.</p>
</section>
<section id="operator-questions-and-verification" class="level2">
<h2 class="anchored" data-anchor-id="operator-questions-and-verification">Operator questions and verification</h2>
<p>Org: recommend <code>v-sekai-fabric</code> since the V-Sekai user record is the load-bearing state, though uro lives at <code>v-sekai/uro</code> and spot-broker at <code>weftspun/spot-broker</code>. Cutover: land the code merge with both old services running, then keep spot-broker’s Fly app alive one week so pinned callers see 410 Gone rather than timeouts. Done when one Fly app serves both the landing and the GPU spend API, one GitHub OAuth app authenticates both, one deploy pipeline builds one release image, and the predecessor RFDs are not backfilled. Move-cost inventory in DETAILS.md.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2138-interactor-shuttle-merges-spot-broker-and-uro/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2138-interactor-shuttle-merges-spot-broker-and-uro/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2137: RFD reports share one sheet</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2137-rfd-reports-share-one-sheet/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>RFD reports published as pages have no shared shape: each one reinvents its header, its tables, and its palette, and the working agreements the documents encode (retractions in place, baselines beside numbers, controls named) have no slot a page reminds an author to fill.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>One template, <code>template.html</code> in this directory, in the PERT sheet’s design system: Libre Franklin over IBM Plex Mono, the paper/ink/critical/done/steel tokens, light and dark themes resolved at the token level. To publish a report, copy the file, replace every bracketed slot, and keep the worked example’s shape.</p>
<p>The layout encodes the agreements rather than describing them:</p>
<ul>
<li>the serial header and stamps mirror the RFD frontmatter;</li>
<li>every measurement table carries its baseline row, and the chosen row takes the green rail;</li>
<li>the figure is an inline SVG in currentColor with labelled arrows, one claim, stated again in its aria-label;</li>
<li>the retraction block is bordered in the accent and sits in place, next to what it retracts;</li>
<li>the controls card lists each planted defect the gate caught;</li>
<li>the provenance foot points at the logbook, the PRs, and the command to re-run, and pairs physical measurements with a household-object equivalent.</li>
</ul>
</section>
<section id="verification" class="level2">
<h2 class="anchored" data-anchor-id="verification">Verification</h2>
<p>The worked example filling the slots is RFD 2134, so the template is demonstrated by a report that shipped rather than by lorem.</p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2137-rfd-reports-share-one-sheet/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2136: The gacha critical path, as a ladder</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2136-the-gacha-critical-path/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The prior draft of this RFD ran a PERT network with a chain A → I → D → E → G, and I → D skipped every step that turns a text prompt into a mesh good enough to skin: no image-to-3D via Pixal3D, no EditScore judge, no repair loop. A pull is not a gacha item without those, so the network was drawing a schedule around a pipeline that did not yet exist end to end.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Rebuild the plan as a ladder, in Gall’s Law’s sense: each rung is a small working system that the next one extends, and no rung is added until the one below it demonstrably runs. That replaces the parallel tracks with a sequence where every step shows something, and it puts Pixal3D and EditScore on the spine where they belong.</p>
<p>The ladder, bottom to top:</p>
<ol start="0" type="1">
<li><strong>Language prompt → image.</strong> OmniGen2 renders a reference image from a text prompt. Pixal3D takes an image, not text, so this rung is the ground the rest stands on. An image comes out.</li>
<li><strong>Image → mesh.</strong> Pixal3D renders one mesh from the reference image on the desk 3090. A mesh comes out. Whether it is good is the next rung’s problem.</li>
<li><strong>Prompt → mesh → judged.</strong> EditScore scores the mesh against the prompt. A number comes out. Whether the number is trusted is the next rung’s problem.</li>
<li><strong>Prompt → mesh → judged → repaired.</strong> VoxHammer runs the repair pass on below-threshold meshes; they are rejudged and the loop bounds to N attempts. Every prompt yields a mesh with a passing score, or a recorded refusal.</li>
<li><strong>Prompt → passing mesh → skinned.</strong> SkinTokens runs in skin-mode against the canonical ANNY skeleton and produces a rig that bends without collapsing (EditScore on posed frames is the QA gate).</li>
<li><strong>Prompt → skinned mesh → tagged.</strong> The canonical See-Through partition (VALID_BODY_PARTS_V3, 23 tags; RFD 1121 audited) is recovered on the mesh by treating the mesh’s partition as corruption: VoxHammer proposes repairs toward the canonical partition, EditScore judges each proposal, the loop bounds to N attempts. Written to the mesh as a per-vertex tag primvar. Parts are addressable.</li>
<li><strong>Prompt → tagged rig → VRM.</strong> The seed-to-VRM assembly runs end to end from a single command: a portable, editable character file.</li>
<li><strong>Prompt list → pool.</strong> The seed-to-VRM command runs against a list of prompts, gated by rent from the spot-broker when the desk is not enough. About 50 VRMs, judged and reproducible by seed.</li>
<li><strong>Pool → roll button.</strong> A page with a roll button dispenses one VRM per pull, downloadable.</li>
<li><strong>Public.</strong> The page is hosted with a sponsor link and an automation-disclosure page.</li>
</ol>
<p>Each rung is a demo you can show. A rung is “done” when it produces its output from the previous rung’s output, and a control run on a known-broken input fails. The order stays fixed: skipping a rung is the failure mode this RFD replaces.</p>
</section>
<section id="verification" class="level2">
<h2 class="anchored" data-anchor-id="verification">Verification</h2>
<p><code>page.qmd</code> beside this file draws the ladder and pairs each rung with its inputs, its output, and the negative control that certifies it. The spend infrastructure the higher rungs lean on is live (RFDs 2133–2135); the two operator-side blockers (vast.ai key, broker token) bite at rung 7, not before.</p>
</section>
<section id="figure" class="level2">
<h2 class="anchored" data-anchor-id="figure">Figure</h2>
<p><a href="../../rfd/2136-the-gacha-critical-path/page.html">The report as a page</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2136-the-gacha-critical-path/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2135: Checks run where the credentials already are</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2135-checks-run-where-the-credentials-already-are/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The weftspun-fdb backup needed a staleness gate, and the two obvious homes were both wrong. CI has no production access, and granting it some means a new credential with a new blast radius. The spot-broker keeper holds spend authority, and an admin service that accumulates monitoring scripts becomes the home of every capability.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>A production check runs on the machine being checked, because that is the one place the credentials already are: nothing new is granted anywhere. It publishes a health file over a local httpd, and a Fly machine check turns the file into a pass or fail in <code>fly status</code>.</p>
<p>Two reference cases ship, both on weftspun-fdb. <code>backup_fresh</code> reads the backup layer’s own metadata; a backup is fresh only when it is running and its restorable point is close. <code>cluster_health</code> fails until the data state is healthy and a zone can be lost without losing data, so a rolling deploy waits out re-replication after each restart, the way the Kubernetes FDB operator gates its own rolls.</p>
<p>Every check refuses to arm unless its self-test controls fire in both directions, and an unreadable signal always reads as failure. The measurements behind both checks, including the two backups that silently self-completed and the curl signing limits that reshaped the probe, are in DETAILS.md and the logbook.</p>
</section>
<section id="verification" class="level2">
<h2 class="anchored" data-anchor-id="verification">Verification</h2>
<p>The roll gate’s first live exercise was its own deploy: after each machine restart the check held red (<code>data_healthy=no</code>) through re-replication and the roll waited, then all three machines converged to 2 of 2 checks passing.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2135-checks-run-where-the-credentials-already-are/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2135-checks-run-where-the-credentials-already-are/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2134: Cluster TLS is decided before data, and certificates carry v3 extensions</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2134-cluster-tls-is-decided-before-data/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The weftspun-fdb cluster came up plaintext, and its backup could not reach the blob store: FoundationDB uses one TLS policy for peers and for S3, so a cluster with no trust store cannot speak HTTPS to Tigris. Turning TLS on after the fact hit two walls, one known and one new.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Mutual TLS from a private CA, per-machine certificates named by Fly machine ID, and one client certificate per consuming service, all carrying X.509v3 extensions, because FoundationDB’s preverification rejects a bare <code>openssl req -x509</code> CA as <code>invalid CA certificate</code>. The profile, the local Docker proof with its negative control, and the full procedure are in DETAILS.md.</p>
<p>The known wall is recorded in datasource-store’s fdb-entrypoint and held exactly: there is no in-place path from a plaintext cluster to a TLS one, because <code>:tls</code> is part of a coordinator’s address and the coordinated state on disk names addresses that no longer exist. The gated <code>WEFT_FDB_RESET=1</code> wipe is the remedy, so TLS is decided before there is data worth keeping; this cluster held one test event.</p>
<p>A client is a TLS peer like any other: it presents its own leaf (<code>CN=fdb-spot-broker.chibifire.com</code>) through the <code>FDB_TLS_*</code> env vars libfdb_c reads, and verifies the cluster with the same rule the cluster uses (<code>Check.Valid=1,S.CN&gt;=fdb-,S.CN&lt;=.chibifire.com</code>).</p>
</section>
<section id="verification" class="level2">
<h2 class="anchored" data-anchor-id="verification">Verification</h2>
<p>A matched pair in local Docker before any push: v3 certificates form a database; the previous extension-less certificates reproduce the production failure on the same server and rule. In prod, a ledger event survived a full machine replacement and read back over TLS.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2134-cluster-tls-is-decided-before-data/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2134-cluster-tls-is-decided-before-data/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 2133: The pool rents from the spot book, gated on requirements first</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/2133-the-pool-rents-from-the-spot-book/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Pool generation wants days of GPU that the desk card should not give up: the 3090 is the interactive seat for rigging and judging, and a batch that owns it for two days stalls the critical path it feeds.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Rent single RTX 4090s from the vast.ai book, requirements before price. A qualifying host carries CUDA at 12.8 or newer, 100 GB of allocatable disk, 32 GB of RAM, and 200 Mbit/s down; the measurements behind each gate are in DETAILS.md, with the price distributions that show what the gates cost. The gates exist for the cheap unqualified boxes: the sub-15-cent listings that flicker through the book bought their price with 52 GB disks and 16 GB hosts, and a model pull over a starved link is paid idle time.</p>
<p>Interruptible is the planning tier, near 20 cents per hour at the qualified p25; on-demand is bought when a qualified outlier dips, and sub-floor outliers were measured living minutes, not hours. Pool work is seed-checkpointed, so an interruption costs one pull.</p>
<p>The RunPod teardown rule applies unchanged: results are pushed when produced, the instance is destroyed after use, and the destruction is double-checked. The API key lives in the user environment, read from the password manager, never in a repository or a transcript.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1163 keeps the desk card for the loops this rule protects. The demo plan this feeds is charted in the Gacha Critical Path artifact; pool generation is its activity E.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/2133-the-pool-rents-from-the-spot-book/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/2133-the-pool-rents-from-the-spot-book/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1174: Publish the security rules against SOC 2 and ISO 27001</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1174-publish-the-security-rules-against-soc2-and-iso27001/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>The workspace’s rules live in <code>CLAUDE.md</code> and <code>BLOCKLIST.md</code>. An outside reader who asks “do you meet SOC 2?” or “which ISO 27001 controls apply?” receives a paragraph, not a control identifier. Coverage the rules already give reads as absent.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Publish the rules against two known frames: SOC 2 (2017 Trust Services Criteria, revised 2022) and ISO/IEC 27001:2022 Annex A. Neither replaces a rule; each names one under an identifier the outside reader already knows. Documentation-only, FOSS: no auditor, no certified ISMS, no third-party attestation.</p>
<p>The mapping lives in a new <code>SECURITY-CONTROLS.md</code>. Each row cites its rule by file and line and its control by identifier and version. A row without a rule states a gap and holds no identifier.</p>
<p><code>scripts/check_security_controls.py</code> gates it: resolve every citation, verify every identifier against a machine-readable register beside the mapping, fail on either miss, negative control included. <code>DETAILS.md</code> carries the coverage table, the gap list, and the argument for two frames rather than one.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li>Coverage table, gap list, and the two-frame argument: <code>DETAILS.md</code></li>
<li>Unwritten until <code>committed</code>, and costed in <code>DETAILS.md</code>: the gate <code>scripts/check_security_controls.py</code> and both control-register CSVs</li>
</ol>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1000 (conventions). RFD 1125 (AI-trope gate).</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1174-publish-the-security-rules-against-soc2-and-iso27001/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1174-publish-the-security-rules-against-soc2-and-iso27001/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1173: A multimodal avatar pipeline</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1173-a-multimodal-diffusion-pipeline/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>A real-time avatar demo (Gemma Avatar architecture, 9k+ robots) needs sub-500ms first-packet latency with text + image + audio. MaskScore (self-supervised edit scoring) needs models that handle all modalities to construct training data.</p>
<p>EditScore is functionally complete in the NAND-gate sense: every generation task reduces to an edit. One reward covers every modality.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Qwen3-Omni for understanding, text, and speech. Wan-VACE for image generation and editing. Qwen3-Omni outputs text and audio only; it does not generate images.</p>
<pre><code>thinker     Qwen3-Omni thinker         Apache 2.0   text + image + audio + video → text
talker      Qwen3-Omni talker          Apache 2.0   voice-cloning speech
image gen   Wan-VACE                   Apache 2.0   text/image → image
3D stage    Pixal3D → VoxHammer        Apache 2.0   image → mesh
scoring     MaskScore + EditScore      n/a           self-supervised reward</code></pre>
<p>MaskScore constructs edit triples by masking, reconstructing, and scoring on decoded outputs. The reward model RL fine-tunes the generators via EditScore.</p>
<p>VRAM budget, sweep results, and the LLaDA retraction are in <a href="../../rfd/1173-a-multimodal-diffusion-pipeline/DETAILS.html">DETAILS.md</a>. The eight MaskScore dataset stubs are in <a href="../../rfd/1173-a-multimodal-diffusion-pipeline/MASKSCORE.html">MASKSCORE.md</a>.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1172, RFD 1166, RFD 1170.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1173-a-multimodal-diffusion-pipeline/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1173-a-multimodal-diffusion-pipeline/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1172: A diffusion LM does not land on the NPU</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1172-a-diffusion-lm-does-not-land-on-the-npu/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Diffusion language models generate text by unmasking a full sequence over repeated denoising passes instead of decoding one token at a time. The strongest one whose weights we could hold is LLaDA2.1-flash: a 100B mixture of experts with 6.1B active parameters, Apache 2.0, ungated, with the best benchmark table any dLLM has published (MMLU-Pro 76.6, HumanEval+ 89.6). The question was whether it, or any dLLM, could run on the laptop’s NPU.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>It cannot, and the XDNA blocklist row stands unchanged.</p>
<p>Three facts settle it, each sourced in DETAILS.md. The vendor’s LLM flows exclude this NPU generation: every supported path requires the newer 50 TOPS part, and the one prototype flow that reaches ours measured 2.3 tokens per second on the NPU against 7.8 on the CPU beside it. The inference pattern is heavier than autoregressive decoding: bidirectional attention over the full sequence, dozens of passes, no KV cache in the standard formulation. The one published NPU deployment of a dLLM anywhere runs an 8B model on a phone accelerator in the 45 TOPS class, and it rewrote the algorithm to get there. Ours peaks at 10.</p>
<p>If diffusion text generation earns a place in this workspace, it runs on the 3090 or a rented GPU. DiffusionGemma 26B-A4B and LLaDA2.1-mini, both Apache 2.0, are the sizes that fit a desk card.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li>Candidate table, sources, and the throughput numbers: <code>DETAILS.md</code></li>
<li>The XDNA row in <code>BLOCKLIST.md</code> carries the standing toolchain argument.</li>
</ol>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1172-a-diffusion-lm-does-not-land-on-the-npu/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1172-a-diffusion-lm-does-not-land-on-the-npu/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1171: The presence loop, and every role in it</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1171-the-presence-loop-and-every-role-in-it/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>RFD 1166 ranked twelve models against each other and never says <strong>what any of them is for</strong>, so a reader cannot tell which stage is missing. Ranking stages of one pipeline against each other was the error.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>One loop, four movements, and each runs both ways:</p>
<pre><code>forward                     inverse

make    a description -&gt; a body   fit      a picture -&gt; the body
dress   a layer onto the body     recover  the body out from under
be it   a person supplies motion  friend   a model supplies it</code></pre>
<p><strong>Each inverse is under-determined, which is why every one has a checker</strong> and why Kimodo sits beside rf-detr rather than behind it.</p>
<p><strong>The See-Through taxonomy is the vocabulary.</strong> <code>VALID_BODY_PARTS_V3</code> names 23 parts, nine worn and the rest body, and <strong>that line is the try-on axis</strong>. A try-on is then masking treated as corruption: remove <code>topwear</code> and LaMa fills the hole the garment leaves.</p>
<p><strong>The boundary is subtraction, not segmentation.</strong> The posed ANNY mesh gives the body outline through <code>silhouette.py</code>; MoGe depth gives the person’s outline and the camera both project through. What lies between is worn — no taxonomy-aware segmenter, so no labelled corpus. <code>contour.py</code> makes either a fixed ring. <code>DETAILS.md</code> places every candidate and names the empty stages.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1166 has the measurements; 1168, 1169 and 1170 the mechanisms.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1171-the-presence-loop-and-every-role-in-it/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1171-the-presence-loop-and-every-role-in-it/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1170: A cleanroom presence loop, and which components swap</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1170-a-cleanroom-presence-loop/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p><code>victor/gemma-avatar</code> runs the loop this workspace wants — speak, be understood, be answered by a lip-syncing face — and states <strong>no licence</strong>. Its integration code cannot be taken.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Study it, take nothing, rebuild from the components it names — cheap, because <strong>every component is separately licensed and clean; only the glue is unlicensed.</strong></p>
<pre><code>their stage        licence      ours

silero-VAD         MIT          keep
parakeet-tdt-1.1b  CC-BY-4.0    Qwen3-ASR-1.7B, Apache-2.0
gemma-4-31B, API   Apache-2.0   Qwen3-VL-8B, local
Qwen3-TTS 12Hz     Apache-2.0   already ours
TalkingHead        MIT          keep, or ANNY through Godot
three.js           MIT          Godot, with Mitsuba as oracle</code></pre>
<p><strong>Their TTS choice is ours, independently</strong> — the same <code>Qwen3-TTS-12Hz-1.7B-CustomVoice</code> RFD 1166 seated at 4 the same day.</p>
<p><strong>Two stages swap for reasons already held here.</strong> Parakeet is licence-clean but has no compiled path, while RFD 1169 puts Qwen3-ASR’s encoder inside <code>DEVICE_OPS</code>. Gemma 4 is Apache-2.0 — RFD 1155 abandoned it on shape, not licence — but 31 B does not fit 8 GB and a hosted API cannot be a corpus source. <strong>The lip-sync is the part we lack</strong>, and <code>DETAILS.md</code> carries what TalkingHead does and what is unknown.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1169 supplies the ear and the voice. RFD 1155 abandoned Gemma 4.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1170-a-cleanroom-presence-loop/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1170-a-cleanroom-presence-loop/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1169: The audio tower for Qwen3-VL, and which half compiles</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1169-the-audio-tower-for-qwen3-vl/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>RFD 1155 abandoned Gemma 4 and left one thing open: what Qwen3-VL does not carry is sound. An AuT encoder with an MLP projector, taking 128-bin log-mel into the decoder’s 4096 space, closes that — the pattern RFD 1157 established for vision.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p><strong>The tower is a plausible device half.</strong> A Whisper-shaped encoder is Conv, MatMul, Softmax, LayerNormalization and gelu’s Erf, all inside <code>DEVICE_OPS</code>, and <code>PROJECTOR_TYPE_QWEN3A</code>’s <code>conv2d</code> front end shows the log-mel is a single-channel image — escaping the input-rank refusal that stopped Pixal3D.</p>
<p><strong>The blocker is our own fork.</strong> <code>clip_init_hailo</code> hardcodes <code>CLIP_MODALITY_VISION</code>; the <code>mtmd</code> around it already carries <code>CLIP_MODALITY_AUDIO</code> and <code>PROJECTOR_TYPE_QWEN3A</code>.</p>
<p><strong>No projector transfers, and the AuT source is old.</strong> Qwen3-Omni is 1280 wide over a 2048 decoder, has no standalone checkpoint, and predates Qwen3-VL-8B. Qwen3.5-Omni has no official release. <strong>Take <code>Qwen3-ASR-1.7B</code></strong> instead — Apache-2.0, ungated, 128-bin, newer than our base, 2.04 GB at eight bits.</p>
<p><strong>A voice is available; it is the acceleration that is not.</strong> <code>Qwen3-TTS-12Hz-1.7B-CustomVoice</code> is Apache-2.0 and clones. Its autoregressive stage is RFD 1126’s obstacle and runs on the host — at 12 Hz, 120 steps for ten seconds of speech. <code>DETAILS.md</code> has the widths, the dates and the fixed window.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1155 left this open. RFD 1157 holds the vision tower.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1169-the-audio-tower-for-qwen3-vl/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1169-the-audio-tower-for-qwen3-vl/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1168: Segment the 3D latent with rf-detr, and treat masking as corruption</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1168-segmenting-the-3d-latent-with-rf-detr/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>RFD 1166 dropped See-Through, so layer decomposition has no model. The obvious 3D replacement is gone too: P3-SAM / Hunyuan3D-Part is blocklisted on a territory-restricted licence.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Segment in 3D, from parts already held. RF-DETR-Seg has a <code>SegmentationHead</code> that <code>convert_segmentation_to_gguf.py</code> converts, so the segmenter is the one model at rung 3. VoxHammer’s <code>extract_feature.py:96</code> projects per-view tensors onto voxel centres with <code>F.grid_sample</code>, over the <code>sphere_hammersley_sequence</code> views CLAUDE.md mandates. <strong>The lift is that call with a different payload:</strong> class logits where DINOv2 patch tokens go now.</p>
<p>3D is the right place: <code>front hair</code> against <code>back hair</code> is a depth relation, and a rendered view is where it is destroyed.</p>
<p><strong>Masking is corruption.</strong> A layer is only a layer if it is whole, so emitting <code>back hair</code> means restoring what <code>front hair</code> hid.</p>
<p><strong>LaMa fills the hole, and is the licence-clean half of See-Through</strong> — <code>dreMaz/AnimeMangaInpainting</code>, MIT over Apache-2.0, tuned for this domain. It will not compile: its Fourier convolutions call <code>rfftn</code>, and no Fourier operator is in <code>DEVICE_OPS</code>. CycleGAN is the opposite trade.</p>
<p><strong>Unbuilt.</strong> <code>DETAILS.md</code> bounds the COCO classes and the resolution, supplies the corpus from corrupt-clean render pairs, and gives two tests costing no training.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1166 drops See-Through. RFD 1167 places rf-detr at rung 3.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1168-segmenting-the-3d-latent-with-rf-detr/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1168-segmenting-the-3d-latent-with-rf-detr/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1167: The ladder, and which rung each model is on</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1167-the-ladder-and-where-each-model-stands/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>RFD 1166 ranks what is worth doing and not what has been done. The two are read as one: a model near the top looks advanced when it may never have been exported, and one near the bottom may be further along than anything above it.</p>
<p>A rank is a judgment and a rung is a fact. One table for both lets an opinion about value borrow the authority of a measurement.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Six rungs, each a thing that either happened or did not:</p>
<pre><code>0  assessed    blocklist clear, checkout present
1  exports     reaches ONNX at a fixed shape
2  operators   the operator set is known and compared
3  translates  the Dataflow Compiler accepts the graph
4  quantises   optimize completes and writes a HAR
5  runs        a HEF executes on the device</code></pre>
<p>A model sits on the highest rung it has reached, and the rung below a failure is where it sits: reaching 2 and failing 3 is rung 2.</p>
<p><code>DETAILS.md</code> carries one table per rung. Most of the field is on rung 0, which is the finding rather than an embarrassment: eleven of twelve candidates have never been exported, so the ranking beside them was built from reading rather than running. RFD 1129’s skill gives the procedure for climbing and its order is this order.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1166 ranks the same models. RFD 1129 asks whether operators compile. RFD 1130 measures the device.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1167-the-ladder-and-where-each-model-stands/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1167-the-ladder-and-where-each-model-stands/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1166: How the accelerator candidates were scored</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1166-scoring-the-accelerator-candidates/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Eight RFDs cite a score out of 25 and no document says what the 25 measures, so a reader cannot reproduce it or tell which scores rest on measurement. It was also applied before it was written.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p>Eight dimensions, each scored 0 to 100:</p>
<pre><code>fit        headroom at a workable precision
shape      is the graph fixed-shape
reference  does a working precedent exist
clear      is anything else blocking it
value      what accelerating it buys
adapt      can this desk train, tune or LoRA it
ask        can we get an answer out of it
wanted     does anyone want the thing it does</code></pre>
<p><code>adapt</code> and <code>ask</code> are duals. <code>check_rfd1166_rank.py</code> recomputes the <strong>STAR</strong> order with <code>starvote</code>.</p>
<p><strong>ABANDONED 2026-08-29, and RFD 1171 replaces it.</strong> The ranking asked which candidate is most worth accelerating, and that was the wrong question: these are stages of one loop, not competitors for one device, and a stage does not outrank the stage it feeds. <code>Qwen3-ASR</code> entering at seat 2 made it plain.</p>
<!-- retain-details -->
<p><code>DETAILS.md</code> keeps the table and the measurements that RFD 1171 cites.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1154 to 1162 hold the candidates; RFD 1167 says where each is.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1166-scoring-the-accelerator-candidates/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1166-scoring-the-accelerator-candidates/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
<item>
  <title>RFD 1165: Fine-tuning exhausts the desk card, and batch size is the lever</title>
  <link>https://weftspun.github.io/request-for-discussion/rfd/1165-finetuning-exhausts-the-desk-card/</link>
  <description><![CDATA[ 





<!-- generated by scripts/render_site.py; edit README.md instead -->
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Two walls stopped this compile, and they are different walls.</p>
<p>The first was system memory. Statistics Collector took SIGKILL at Docker’s 30.26 GiB; raising <code>.wslconfig</code> to 48 GB cleared it and the stage completed in 14:58. The run peaked at 39.87 GiB, 85 per cent of the new ceiling and well above the old, so the lift was load-bearing.</p>
<p>The second is video memory, and no amount of system RAM answers it:</p>
<pre><code>AccelerasResourceError: GPU memory has been exhausted. Please
try Quantization-Aware Fine-Tuning with lower batch size.</code></pre>
<p>QAFT ran about thirty minutes of epoch 1 of 4 on 1024 frames and exhausted 24 GiB. RFD 1140 says match the card to the wall you hit; clearing the RAM ceiling only bought the right to meet this one.</p>
</section>
<section id="decision" class="level2">
<h2 class="anchored" data-anchor-id="decision">Decision</h2>
<p><strong>RETRACTED 2026-08-29: this said batch size was the lever, and it is not.</strong> A probe at <code>batch_size=1, epochs=1</code> on 64 frames raised the same <code>AccelerasResourceError</code> after 44 minutes.</p>
<p><strong>The requirement is measured: QAFT needs 32.5 GiB, on an A40.</strong> The desk 3090 holds 24, so the shortfall is 8.5 GiB and no batch size closes it. Separately, <code>a16_w16</code> is refused by this part outright – twelve <code>precision_change</code> layers the target will not take – so <code>a8_w8</code> is the precision ceiling. <code>DETAILS.md</code> carries both.</p>
</section>
<section id="related" class="level2">
<h2 class="anchored" data-anchor-id="related">Related</h2>
<p>RFD 1140 rents the card. RFD 1163 divides the work. RFD 1164 says what the calibration set becomes. RFD 1167 places the rung.</p>
</section>
<section id="details" class="level2">
<h2 class="anchored" data-anchor-id="details">Details</h2>
<p><a href="../../rfd/1165-finetuning-exhausts-the-desk-card/DETAILS.html">The measurements and the retractions</a></p>


</section>

 ]]></description>
  <guid>https://weftspun.github.io/request-for-discussion/rfd/1165-finetuning-exhausts-the-desk-card/</guid>
  <pubDate>Tue, 01 Sep 2026 01:25:01 GMT</pubDate>
</item>
</channel>
</rss>
