<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GnomeMan4201</title>
    <description>The latest articles on DEV Community by GnomeMan4201 (@gnomeman4201).</description>
    <link>https://dev.to/gnomeman4201</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2619990%2F02067c21-a4b3-4278-92cb-0e62d2b0084a.jpeg</url>
      <title>DEV Community: GnomeMan4201</title>
      <link>https://dev.to/gnomeman4201</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gnomeman4201"/>
    <language>en</language>
    <item>
      <title>Can a research review leave a checkable record? Help me break this draft.</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sun, 01 Nov 2026 18:59:51 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/can-a-research-review-leave-a-checkable-record-help-me-break-this-35g1</link>
      <guid>https://dev.to/gnomeman4201/can-a-research-review-leave-a-checkable-record-help-me-break-this-35g1</guid>
      <description>&lt;p&gt;I'm looking for people who will try to break a protocol I've been designing. It's a draft, it has had no outside security review, and I'm not asking anyone to take part in a real review round. I want the design attacked before I put real research through it.&lt;/p&gt;

&lt;p&gt;If you only have a few minutes: read the &lt;a href="https://github.com/GnomeMan4201/review-capsule/blob/d54432f3/reviewrecord/spec/REVIEW_RECORD_SPEC_v0.2.2.md" rel="noopener noreferrer"&gt;specification&lt;/a&gt; and tell me how an author or steward could make a review record look reassuring while hiding something. A concrete counterexample is worth more than general feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I do independent security and LLM research. I have no lab and no formal peer review, and when I ask people for informal feedback, I can't show anyone afterward how that feedback was collected and handled. Things that can go wrong even when everyone is honest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exposure.&lt;/strong&gt; A reviewer may have seen my interpretation, or another reviewer's answer, before forming their own. A signature can't show that didn't happen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editing or omission.&lt;/strong&gt; An assessment could be changed or dropped after it was received, and a third party would struggle to notice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ambiguous time.&lt;/strong&gt; A file date or Git commit timestamp doesn't prove when someone received a packet or sent an assessment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing portable.&lt;/strong&gt; "Three people looked at it" isn't a record another reader can inspect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My own case: I recently published &lt;a href="https://dev.to/gnomeman4201/same-evidence-different-judgment-a-small-experiment-on-implied-conclusions-and-evidence-ordering-ndg"&gt;a DEV.to write-up&lt;/a&gt; of a small exploratory study on how a model judges conclusions against the same stipulated evidence in different orders, alongside &lt;a href="https://github.com/GnomeMan4201/composed-inference-ordering-v1.1" rel="noopener noreferrer"&gt;the raw outputs and a read only audit script&lt;/a&gt;. It has four synthetic cases with author assigned labels, not independently adjudicated ones, and with one response per condition it does not establish an ordering effect. I want those limits visible when I ask others to scrutinize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Review Record tries to make checkable
&lt;/h2&gt;

&lt;p&gt;An author signs a registration that binds a packet and a policy to a round. Reviewers sign their assessments with their own local keys and send only a signed &lt;strong&gt;commitment&lt;/strong&gt; before the steward closes the round. After the close, a reviewer can publish the assessment, and anyone with the complete bundle can check it against the closed commitment log with an inclusion proof.&lt;/p&gt;

&lt;p&gt;The intended claim is narrow: supplied signed objects can be checked for content consistency, commitment linkage, and omissions that show up against retained acknowledgements or external checkpoints. Compared with a public hash then reveal comment, this draft adds signed steward acknowledgements, a hash-chained log, portable inclusion proofs and explicit dispositions. &lt;strong&gt;I have not demonstrated that these additions justify the extra complexity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What it does &lt;strong&gt;not&lt;/strong&gt; show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;that reviewers were independent, unexposed, or didn't collude;&lt;/li&gt;
&lt;li&gt;that blinding worked, or that the research is correct;&lt;/li&gt;
&lt;li&gt;when the packet was registered, because external proof of time isn't finished. Today the code cannot demonstrate that registration was anchored before a reviewer received the packet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reviewer statements about relationships, stakes and prior exposure are signed declarations by the reviewer, not established facts. A count of locks and reveals isn't an integrity verdict.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a round would work
&lt;/h2&gt;

&lt;p&gt;A reviewer generates an encrypted signing key, signs a declaration, examines a frozen packet and policy, and records judgments, including &lt;strong&gt;uncertain&lt;/strong&gt; and &lt;strong&gt;the question needs fixing&lt;/strong&gt;. They sign locally and send only the commitment before close, then may reveal after. Withdrawal doesn't erase a lock. A steward attested withdrawal is labelled as the steward's claim, not the reviewer's consent.&lt;/p&gt;

&lt;p&gt;The author lists prior rounds and gives every concern a public disposition: adopted, under examination, unresolved, or declined, with a reason. Admission is currently at the steward's discretion, which is a documented governance gap.&lt;/p&gt;

&lt;p&gt;This is not an invitation to join a formal round. It still needs command line tools, and I don't yet know how long the workflow takes someone new.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the code stands
&lt;/h2&gt;

&lt;p&gt;At commit &lt;code&gt;d54432f3&lt;/code&gt; (Nov 1, 2026), the draft &lt;a href="https://github.com/GnomeMan4201/review-capsule/pull/2" rel="noopener noreferrer"&gt;PR #2&lt;/a&gt; has the v0.2.2 spec and candidate Python tools for verification, reviewer signing, steward intake/close/reveal, author signing and bundle assembly. GitHub Actions reports &lt;strong&gt;122 synthetic tests passing&lt;/strong&gt; for this revision (&lt;a href="https://github.com/GnomeMan4201/review-capsule/actions/runs/41336824405" rel="noopener noreferrer"&gt;CI run&lt;/a&gt;). These are synthetic tests, not independent cryptographic review or proof of real external timestamp authority. The branch may keep changing, so check the &lt;a href="https://github.com/GnomeMan4201/review-capsule/pull/2/files" rel="noopener noreferrer"&gt;current diff&lt;/a&gt; and its latest CI result.&lt;/p&gt;

&lt;p&gt;A second AI audit identified a real RFC 3161 &lt;strong&gt;wrong target binding defect&lt;/strong&gt; in the earlier code. A new regression reproduced the failure in CI, and a candidate fix now requires both the original request and the signed timestamp to match the specified target. A locally generated test TSA passes those checks; a real external authority has not been qualified. &lt;a href="https://github.com/GnomeMan4201/review-capsule/blob/d54432f3/reviewrecord/docs/TSA_BINDING_REMEDIATION.md" rel="noopener noreferrer"&gt;The defect and regression evidence are recorded here&lt;/a&gt;. This is not independent human security review.&lt;/p&gt;

&lt;p&gt;Open blockers: independently governed TSA trust pins, revocation/key compromise checks, checkable packet release ordering, a real Bitcoin OpenTimestamps proof confirmed by six blocks, admission governance, crash recovery, a second complete verifier in another language, and review by a human cryptographer or security engineer. The sample round's anchor evidence is pending or unverifiable and must stay non passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in 10–15 minutes (Python 3.12+, Linux or similar)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/GnomeMan4201/review-capsule.git
&lt;span class="nb"&gt;cd &lt;/span&gt;review-capsule
git checkout &lt;span class="nt"&gt;--detach&lt;/span&gt; d54432f3
&lt;span class="nb"&gt;cd &lt;/span&gt;reviewrecord
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; unittest discover &lt;span class="nt"&gt;-s&lt;/span&gt; tests &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reproduces the pinned revision, not a moving branch head. I haven't established that every environment finishes within 15 minutes. Useful starting points: &lt;a href="https://github.com/GnomeMan4201/review-capsule/blob/d54432f3/reviewrecord/src/rr/verify.py" rel="noopener noreferrer"&gt;the verifier&lt;/a&gt;, &lt;a href="https://github.com/GnomeMan4201/review-capsule/blob/d54432f3/reviewrecord/tests/test_kill.py" rel="noopener noreferrer"&gt;the six original kill tests&lt;/a&gt;, and the &lt;a href="https://github.com/GnomeMan4201/review-capsule/blob/d54432f3/reviewrecord/docs/ANCHOR_GATE_AUDIT.md" rel="noopener noreferrer"&gt;anchor audit&lt;/a&gt;, which says what isn't established.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd most like challenged
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How could an author or steward omit, delay, suppress or reorder review evidence while the record looks fine?&lt;/li&gt;
&lt;li&gt;Canonical JSON, DSSE signing, Merkle proofs, resource limits and the timestamp trust model.&lt;/li&gt;
&lt;li&gt;Whether the idea is worth doing at all. If a record like this wouldn't change whether you trust an independent research report, please say why. That's a valid result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal failing test or a concrete alternative design is the most useful thing you can send.&lt;/p&gt;

&lt;h2&gt;
  
  
  A lighter way to help
&lt;/h2&gt;

&lt;p&gt;If you'd rather judge evidence than read cryptography, there's an informal page with four synthetic cases where you form your own judgment before seeing the model's responses: &lt;strong&gt;&lt;a href="https://gnomeman4201.github.io/same-evidence-lab/" rel="noopener noreferrer"&gt;Try the five minute evidence lab&lt;/a&gt;&lt;/strong&gt;. It's separate from Review Record, and answers there are not study labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I'll handle what you send
&lt;/h2&gt;

&lt;p&gt;I'll track technical concerns publicly, including ones I decline or can't resolve, with a reason. That tracking is manual for now; there is no automated audit log. Send concerns as a GitHub issue (&lt;a href="https://github.com/GnomeMan4201/review-capsule/issues/new" rel="noopener noreferrer"&gt;protocol and code&lt;/a&gt;; &lt;a href="https://github.com/GnomeMan4201/composed-inference-ordering-v1.1/issues/new" rel="noopener noreferrer"&gt;study&lt;/a&gt;) or a comment below. Tell me whether to credit your handle, your name, or neither.&lt;/p&gt;

&lt;p&gt;I won't call a comment a formal review, and I won't start a real round on the strength of these tests.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cryptography</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Same Evidence, Different Judgment? A Small Experiment on Implied Conclusions and Evidence Ordering</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sat, 31 Oct 2026 02:22:16 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/same-evidence-different-judgment-a-small-experiment-on-implied-conclusions-and-evidence-ordering-ndg</link>
      <guid>https://dev.to/gnomeman4201/same-evidence-different-judgment-a-small-experiment-on-implied-conclusions-and-evidence-ordering-ndg</guid>
      <description>&lt;p&gt;&lt;em&gt;GnomeMan4201 · Study: &lt;code&gt;composed-inference-ordering-v1.1&lt;/code&gt; · Collected October 31, 2026 UTC&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I ran:&lt;/strong&gt; Four synthetic evidence cases × three presentation conditions × three independent tasks: 36 completed responses from &lt;code&gt;gpt-4.1-mini&lt;/code&gt;, with the original failed API attempt retained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I observed:&lt;/strong&gt; Under the frozen parser, 19/36 responses were accepted and 17/36 were rejected solely for Markdown code fences surrounding JSON. A free-form audit endorsed coordination in one condition despite insufficient evidence; a separately prompted explicit judge withheld support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I cannot conclude:&lt;/strong&gt; One response per condition cannot establish that ordering caused the disagreement, or that the behavior generalizes to real retrieval systems.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Study status and disclosure:&lt;/strong&gt; This is a self-conducted exploratory pilot, not peer-reviewed research or a validated detector. I assigned the synthetic case labels, which have not been independently human-adjudicated. AI assistance was used in drafting and computational analysis; repeated computational checks of the same records are not independent scientific review. Public commenters discussed the underlying question but did not conduct or endorse this experiment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The question came from a discussion, not from a benchmark leaderboard
&lt;/h2&gt;

&lt;p&gt;The starting point was Rudratosh Shastri's DEV.to article, &lt;a href="https://dev.to/rudratosh/a-correct-answer-and-a-confident-lie-look-identical-heres-how-i-made-rag-tell-them-apart-2n45"&gt;&lt;em&gt;How to Make RAG Show Its Evidence: Claim Verification at 15M-Document Scale&lt;/em&gt;&lt;/a&gt;, and the discussion beneath it involving Rudratosh, &lt;a href="https://dev.to/squeaky_spirit"&gt;Squeaky&lt;/a&gt; (a &lt;strong&gt;self-described AI agent&lt;/strong&gt; on iLands), and me. The concern was narrower than hallucination detection in general: individually well-supported observations can be composed into a paragraph that &lt;strong&gt;invites&lt;/strong&gt; a broader explanation the evidence does not establish. Checking every explicit atomic statement may miss that implied conclusion.&lt;/p&gt;

&lt;p&gt;In the thread, I used an infrastructure example: two domains can share an IP and publish the same narrative without that alone establishing coordinated operation. Squeaky suggested extracting the conclusion the arrangement invites and treating it as its own claim against the &lt;strong&gt;combined&lt;/strong&gt; cited evidence. The subsequent exchange clarified something I originally underweighted: reordering can probe the judge's consistency, but a stable verdict cannot establish evidentiary correctness. We also discussed keeping surviving explanations separate from any ranking among them, because an alternative can be less plausible without being ruled out. A conclusion that remains unestablished is not necessarily false; the evidence may simply be insufficient to choose between viable explanations. This account is traceable to the actual nested replies: &lt;a href="https://dev.to/gnomeman4201/comment/3j7d4"&gt;my initial question&lt;/a&gt;, &lt;a href="https://dev.to/rudratosh/comment/3j8ao"&gt;Rudratosh's reply about composition&lt;/a&gt;, &lt;a href="https://dev.to/squeaky_spirit/comment/3jaca"&gt;Squeaky's extraction proposal&lt;/a&gt;, &lt;a href="https://dev.to/gnomeman4201/comment/3jbo7"&gt;my distinction between stability and validity&lt;/a&gt;, and &lt;a href="https://dev.to/squeaky_spirit/comment/3jbof"&gt;Squeaky's distinction between surviving explanations and their ranking&lt;/a&gt;. These exchanges motivate the pilot; none of those participants took part in the experiment or endorsed its results.&lt;/p&gt;

&lt;p&gt;That led to four predeclared research questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RQ1:&lt;/strong&gt; Given a proposed relational conclusion, how does the model judge its support against stipulated evidence?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RQ2:&lt;/strong&gt; With the composed paragraph and candidate unchanged, does reversing the &lt;strong&gt;evidence list&lt;/strong&gt; change outputs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RQ3:&lt;/strong&gt; With the evidence list and candidate unchanged, does reversing the &lt;strong&gt;sentences in the paragraph&lt;/strong&gt; change outputs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RQ4:&lt;/strong&gt; When the model must identify its &lt;strong&gt;own implied claim&lt;/strong&gt;, does it distinguish that inference from what the evidence supports?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scope boundary:&lt;/strong&gt; This experiment did &lt;strong&gt;not&lt;/strong&gt; run a retrieval system, inspect real infrastructure, compare &lt;em&gt;not retrieved&lt;/em&gt; with &lt;em&gt;retrieved but inconclusive&lt;/em&gt;, or measure what actual readers infer. The distinction between evidence that was never retrieved and evidence that was read but remains insufficient mattered in the original discussion; this pilot addresses &lt;strong&gt;only the second kind of interpretive gap&lt;/strong&gt;, with all stipulated evidence supplied directly. Here &lt;em&gt;evidence&lt;/em&gt; means synthetic statements in the prompt, not independently sourced observations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related research and the sample-size boundary
&lt;/h2&gt;

&lt;p&gt;Rudratosh's article cites &lt;a href="https://arxiv.org/abs/2307.03172" rel="noopener noreferrer"&gt;Liu et al., &lt;em&gt;Lost in the Middle&lt;/em&gt; (2023)&lt;/a&gt; and &lt;a href="https://arxiv.org/abs/2508.07479" rel="noopener noreferrer"&gt;Veseli et al., &lt;em&gt;Positional Biases Shift as Inputs Approach Context Window Limits&lt;/em&gt; (2025)&lt;/a&gt;. Those studies investigate position effects in much longer contexts and retrieval/answering tasks. Their results are relevant context for asking whether ordering matters, &lt;strong&gt;not validation or replication of this three-sentence synthetic inference experiment&lt;/strong&gt;. The later work also warns against treating the classic lost-in-the-middle pattern as universal.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/rudratosh/a-correct-answer-and-a-confident-lie-look-identical-heres-how-i-made-rag-tell-them-apart-2n45"&gt;original post's sample-size warning&lt;/a&gt; likewise matters. My 12 case-condition trials and one sample per task-condition were &lt;strong&gt;never designed to estimate a failure rate or establish near-zero error&lt;/strong&gt;. No population-level rate, p-value, or causal ordering estimate is justified. Repeating only the one interesting flipped condition &lt;em&gt;after&lt;/em&gt; seeing the output would be a selected follow-up, not a predeclared replication. A stronger prospective study would replicate &lt;strong&gt;both&lt;/strong&gt; matched arrangements and use independent labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why there were two pilot versions
&lt;/h2&gt;

&lt;p&gt;The original &lt;code&gt;v1.0&lt;/code&gt; design rearranged the evidence list but left its compressed composed paragraph fixed. That could not answer the proposed question about ordering within the composition itself. Before any &lt;code&gt;v1.1&lt;/code&gt; live requests, I revised the design: the composed paragraph now contains the three original evidence sentences, either in original or reversed order, while an independent condition reverses only the enumerated evidence list. The prior design is disclosed in the protocol. &lt;strong&gt;v1.0 and v1.1 are different stimuli and are not pooled.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The v1.1 protocol, script, prompts, trial labels, and scoring rules were frozen before live data collection, but my initial draft was prepared with AI assistance; that assistance was not independent adjudication of the labels. The Chromebook decision ledger records acceptance on &lt;strong&gt;October 31, 2026 at 00:43:18 UTC&lt;/strong&gt;. Initial script SHA-256 was &lt;code&gt;ff196d55c0033059ea89b4f5c61e9ec24486b6d7fa6cbe3f47188a11b514cde5&lt;/code&gt;; the canonical manifest digest was &lt;code&gt;114ab37edfcd055932fb2e5ad34d9c5ee8623a4e16fafab0e15f82f7601326dd&lt;/code&gt;. These values are independently checked against the supplied archive. A hash shows byte identity against a recorded value; without a separately trusted external timestamp it does not by itself prove when those bytes existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually tested
&lt;/h2&gt;

&lt;p&gt;I wrote four small hypothetical cases, each consisting of three stipulated factual sentences, a relational conclusion to evaluate, a provisional author-assigned support label, and an alternative interpretation. These labels are &lt;strong&gt;not independently adjudicated ground truth&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;What the hypothetical evidence says&lt;/th&gt;
&lt;th&gt;Candidate conclusion&lt;/th&gt;
&lt;th&gt;Predeclared label&lt;/th&gt;
&lt;th&gt;Why the label is provisional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shared-host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Two domains shared an IP and published narrative X during one observation window&lt;/td&gt;
&lt;td&gt;Their operators coordinated publication&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shared hosting and independent publication are also compatible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;same-owner-control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Separate signed records identify Organization Q as operator of each domain for the same window&lt;/td&gt;
&lt;td&gt;The records identify a common operator&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUPPORTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The signed records are stipulated authentic &lt;em&gt;within the hypothetical&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;temporal-leap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain A published narrative X at 10:00; Domain B at 10:02&lt;/td&gt;
&lt;td&gt;B copied from A&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Both could have received X from another source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;direct-coordination-control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An authenticated joint release signed by both operators states that they coordinated publication&lt;/td&gt;
&lt;td&gt;According to the release, the operators coordinated publication&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUPPORTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The label concerns what that release establishes, not unrelated collaboration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For each case I prepared three conditions, changing sentence &lt;strong&gt;order only&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;baseline&lt;/code&gt;: evidence list 1–2–3, paragraph 1–2–3;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;evidence_reverse&lt;/code&gt;: evidence list 3–2–1, paragraph 1–2–3;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paragraph_reverse&lt;/code&gt;: evidence list 1–2–3, paragraph 3–2–1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of the 12 case-condition trials received three &lt;strong&gt;separate, stateless&lt;/strong&gt; requests to the same API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;extract&lt;/code&gt;:&lt;/strong&gt; read only the composed paragraph; identify its strongest invited relational claim, without a proposed conclusion or evidence list;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;judge&lt;/code&gt;:&lt;/strong&gt; inspect the stipulated evidence, composed paragraph, and a &lt;strong&gt;provided&lt;/strong&gt; candidate conclusion; return &lt;code&gt;SUPPORTED&lt;/code&gt;, &lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;, or &lt;code&gt;ABSTAIN&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;audit&lt;/code&gt;:&lt;/strong&gt; inspect evidence and paragraph, identify an implied claim &lt;strong&gt;itself&lt;/strong&gt;, and judge whether that self-selected claim is supported.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tasks are not interchangeable. The &lt;code&gt;judge&lt;/code&gt; has the desired candidate supplied to it; the &lt;code&gt;audit&lt;/code&gt; must find one. The &lt;code&gt;extract&lt;/code&gt; task sees the &lt;strong&gt;exact same input&lt;/strong&gt; in &lt;code&gt;baseline&lt;/code&gt; and &lt;code&gt;evidence_reverse&lt;/code&gt;, because it does not receive the evidence list. Differences between those two extract results cannot be evidence-list effects.&lt;/p&gt;

&lt;p&gt;The requests used OpenAI's Responses API with requested model &lt;code&gt;gpt-4.1-mini&lt;/code&gt;, &lt;code&gt;max_output_tokens=900&lt;/code&gt;, &lt;code&gt;store=false&lt;/code&gt;, and no temperature explicitly specified in the request. The returned model identifier for all 36 completed requests was &lt;code&gt;gpt-4.1-mini-2025-04-14&lt;/code&gt;; response metadata reported &lt;code&gt;temperature=1.0&lt;/code&gt; and &lt;code&gt;top_p=1.0&lt;/code&gt;. The test ran in Python 3.11.2 on Debian GNU/Linux 12 in a Chromebook Linux environment. The 12 trial positions were shuffled using a fixed scheduling seed of 42; &lt;strong&gt;that seed did not control model generation&lt;/strong&gt;. Each task-condition was sampled once, with no replicate set or randomized presentation to a reader population.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution record, including the failure
&lt;/h2&gt;

&lt;p&gt;The first live attempt (&lt;code&gt;temporal-leap:evidence_reverse&lt;/code&gt;, task &lt;code&gt;extract&lt;/code&gt;) returned HTTP &lt;strong&gt;429&lt;/strong&gt; at &lt;code&gt;2026-10-31T00:45:06+00:00&lt;/code&gt; and produced no model verdict. That failure was appended to &lt;code&gt;model_raw.jsonl&lt;/code&gt; and &lt;code&gt;events.jsonl&lt;/code&gt;. After API credits were added, execution resumed with an explicit retry flag, keeping the failed attempt instead of overwriting it. The earlier successful responses were skipped automatically during completion of the remaining trials.&lt;/p&gt;

&lt;p&gt;The retained record has &lt;strong&gt;37 request starts, 37 matching finishes, 36 completed API responses, and one HTTP 429 failure&lt;/strong&gt;. There are no unresolved starts and no duplicate successful task-condition entries. The 36 successful outputs span the 12 planned trials, three tasks each. All 36 completed response records report the same model identifier. The archive contains full returned response objects, exact prompts and their per-trial hashes, and UTC events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results under the frozen scoring rule
&lt;/h2&gt;

&lt;p&gt;The original parser accepted only a JSON object returned directly as the response text. &lt;strong&gt;Nineteen of 36 responses met that strict formatting rule. Seventeen did not&lt;/strong&gt;, because the model wrapped its otherwise readable JSON object in Markdown code fences. All 17 were returned with API status &lt;code&gt;completed&lt;/code&gt;: this is an &lt;strong&gt;output-format compliance failure&lt;/strong&gt;, not a transport failure, and not a model abstention.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Strictly valid&lt;/th&gt;
&lt;th&gt;Fenced / invalid under frozen rule&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;extract&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;judge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;audit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;19&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;17&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the six strictly valid &lt;code&gt;judge&lt;/code&gt; responses, &lt;strong&gt;6 matched the author-assigned case labels, 0 disagreed, and 0 abstained&lt;/strong&gt;. This is &lt;strong&gt;6 of 6 valid explicit-judge outputs&lt;/strong&gt;, not 6 out of all 12 judging trials, and certainly not proof of an independently established 100% accuracy rate. The remaining six judge outputs failed the frozen format rule.&lt;/p&gt;

&lt;p&gt;One &lt;strong&gt;strictly valid&lt;/strong&gt; comparison is especially relevant. On the &lt;code&gt;shared-host&lt;/code&gt; case, the &lt;code&gt;audit&lt;/code&gt; task produced:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Model's self-selected relation&lt;/th&gt;
&lt;th&gt;Audit verdict&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;baseline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COORDINATION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Strictly valid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;evidence_reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COORDINATION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fenced / invalid in frozen score&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paragraph_reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COORDINATION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;SUPPORTED&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strictly valid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both baseline and paragraph-reversed audits addressed substantially the same question of whether the domains coordinated publication. In the paragraph-reversed condition, the audit explicitly treated coincident publication and shared IP as establishing coordination, despite the synthetic case's predeclared counter-explanation. In &lt;strong&gt;the same paragraph-reversed trial&lt;/strong&gt;, the independently requested explicit &lt;code&gt;judge&lt;/code&gt; instead returned &lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is an &lt;strong&gt;observed disagreement&lt;/strong&gt; between the two prompt tasks, and an observed difference between audit outputs under different paragraph orders. These are not two independent adjudicators: both requests used the same model, with different instructions. It does &lt;strong&gt;not&lt;/strong&gt; establish that paragraph order caused the difference: there was one request per condition, with uncontrolled model sampling. A stable or changing verdict in this setting is a description of responses, not a causal estimate.&lt;/p&gt;

&lt;p&gt;Among strictly valid baseline-versus-paragraph-reversal audit pairs, &lt;strong&gt;one of three&lt;/strong&gt; changed verdict. There were &lt;strong&gt;no&lt;/strong&gt; strictly valid audit baseline-versus-evidence-reversal pairs, because all four evidence-reversed audit responses used fenced JSON. For the strict explicit &lt;code&gt;judge&lt;/code&gt;, only &lt;strong&gt;one&lt;/strong&gt; baseline-versus-paragraph-reversal pair had two valid responses; it did not change. No strict baseline-versus-evidence-reversal judge pair was complete. Reporting a global strict-format flip percentage here would conceal those uneven denominators.&lt;/p&gt;

&lt;h2&gt;
  
  
  A separate, clearly labeled exploratory analysis of the fenced responses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This section does not change the frozen scorer or its published primary counts.&lt;/strong&gt; I inspected the 17 raw outputs that were rejected for formatting. All 17 consist of exactly one Markdown-fenced JSON object with the expected task fields. Removing only the opening and closing code fences permits syntactic parsing and schema checks. The original strings remain untouched in the archive.&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;post-run format-normalized&lt;/strong&gt; reading produces a complete descriptive matrix:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;Author label&lt;/th&gt;
&lt;th&gt;Explicit &lt;code&gt;judge&lt;/code&gt;: baseline / evidence reverse / paragraph reverse&lt;/th&gt;
&lt;th&gt;Self-selected &lt;code&gt;audit&lt;/code&gt;: same three conditions&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;extract&lt;/code&gt; relation: same three conditions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shared-host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NE&lt;/td&gt;
&lt;td&gt;NE / NE / NE&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NE / NE / S&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;COORDINATION / COORDINATION / COORDINATION&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;same-owner-control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;S / S / S&lt;/td&gt;
&lt;td&gt;S / S / S&lt;/td&gt;
&lt;td&gt;COMMON_OPERATOR / COORDINATION / COORDINATION&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;temporal-leap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NE&lt;/td&gt;
&lt;td&gt;NE / NE / NE&lt;/td&gt;
&lt;td&gt;NE / NE / NE&lt;/td&gt;
&lt;td&gt;COPYING / COPYING / COPYING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;direct-coordination-control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;S / S / S&lt;/td&gt;
&lt;td&gt;S / S / S&lt;/td&gt;
&lt;td&gt;COORDINATION / COORDINATION / COORDINATION&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here &lt;code&gt;NE&lt;/code&gt; means &lt;code&gt;NOT_ESTABLISHED&lt;/code&gt;; &lt;code&gt;S&lt;/code&gt; means &lt;code&gt;SUPPORTED&lt;/code&gt;. These are &lt;strong&gt;exploratory&lt;/strong&gt; decoded readings, not retroactively valid frozen-protocol outputs.&lt;/p&gt;

&lt;p&gt;In this secondary reading, all &lt;strong&gt;12/12&lt;/strong&gt; explicit judge outputs match the author-assigned labels; no explicit-judge verdict changes across the eight baseline/reversal comparisons (four cases × two reversals). The open audit has &lt;strong&gt;one verdict difference among eight&lt;/strong&gt; comparable baseline/reversal comparisons, the &lt;code&gt;shared-host&lt;/code&gt; paragraph-reversal result described above. Do &lt;strong&gt;not&lt;/strong&gt; treat 12/12 as externally validated accuracy: the author supplied the target claim and labels, and the model saw clear synthetic premises.&lt;/p&gt;

&lt;p&gt;There is also a useful warning about treating category changes as ordering effects. In &lt;code&gt;same-owner-control&lt;/code&gt;, the &lt;code&gt;extract&lt;/code&gt; task returned &lt;code&gt;COMMON_OPERATOR&lt;/code&gt; for &lt;code&gt;baseline&lt;/code&gt; but &lt;code&gt;COORDINATION&lt;/code&gt; for &lt;code&gt;evidence_reverse&lt;/code&gt;, &lt;strong&gt;even though those two extraction prompts had identical instructions and paragraph text&lt;/strong&gt;. Both outputs described Organization Q operating both domains. The different category labels therefore cannot be attributed to the evidence-list reversal; that list was never in the extractor's input. The same category drift appears in the paragraph-reversed extraction, but without repeated trials the cause is unresolved. Similarly, the audit's &lt;code&gt;COORDINATION&lt;/code&gt; tag sometimes describes &lt;strong&gt;common operation&lt;/strong&gt;, not evidence of coordinated publication. This weakens any attempt to score relation tags as interchangeable with actual claim semantics.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the pilot does and does not answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Observed in the archive:&lt;/strong&gt; a single open-audit response endorsed coordination from a shared IP and shared publication observations where another open-audit request, and the explicit judge of that same reversed paragraph, withheld support. The fixed judge's complete exploratory verdict set was stable. The frozen data-collection record includes 17 strict-format failures and an earlier HTTP 429 failure, all retained. The same-owner extractor exhibited category drift even under identical model-facing input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not demonstrated:&lt;/strong&gt; that rearranging sentences &lt;em&gt;caused&lt;/em&gt; the audit's disagreement; that any reader would infer coordination from these particular paragraphs; that a RAG pipeline would fail similarly; that an independently judged model can reliably detect implied claims; or that all four author labels are independently established. This pilot also does not distinguish &lt;em&gt;not retrieved&lt;/em&gt; from &lt;em&gt;retrieved but insufficient&lt;/em&gt;—all hypothetical evidence was supplied directly, and no retrieval process was run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further limitations:&lt;/strong&gt; four deliberately chosen cases; simplistic positive controls; two negative cases using obvious unsupported leaps; unblinded, self-evaluating &lt;code&gt;audit&lt;/code&gt;; one sample per task/condition; no second human adjudicator of implied meaning or rival plausibility; no test of evidence freshness, provenance, or real-world attribution; no p-values or population effect estimates. A response may be correct about a supplied candidate while failing to identify an implied conclusion in free composition, and those must remain distinct questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kill criterion:&lt;/strong&gt; If the inputs, comparison denominators, or label review cannot separate mere verdict variability from evidentiary validity, the study is &lt;strong&gt;inconclusive for detection-capability claims&lt;/strong&gt;. On that criterion, v1.1 is useful as a transparent exploratory record and as a concrete counterexample to overinterpreting a single self-audit, &lt;strong&gt;not&lt;/strong&gt; a qualified detector or generalized causal experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The central lesson of this small run is not that an ordering attack was proven, nor that explicit verification solved the problem. In one trial, the &lt;strong&gt;explicit judge withheld support for coordination while the open audit endorsed it from the same synthetic observations&lt;/strong&gt;. When the evidence was held constant across independently requested conditions, the audit's verdict also differed once. Because model sampling was not replicated or controlled, the cause remains open. The strict-parser failures are part of the result, not numbers to be silently repaired away.&lt;/p&gt;

&lt;p&gt;That is the result I can bring back to the discussion: one transparent observed disagreement, an explicit non-result for causal attribution, a complete record of format failures, and materials another person can inspect or rerun from the &lt;a href="https://github.com/GnomeMan4201/composed-inference-ordering-v1.1/blob/main/Research_v1_1.zip" rel="noopener noreferrer"&gt;public research archive&lt;/a&gt;. A stronger next study would preregister independently assessed, blinded implication labels and rival explanations, add repeats per condition, and keep extraction, explicit judgment, and free-form audit scores separate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Appendix A — Reproducibility, hashes, and complete trace
&lt;/h2&gt;

&lt;p&gt;The raw archive is &lt;code&gt;evidence_inference_results_v1_1.zip&lt;/code&gt;, with SHA-256:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;b117050aa57dd573ac8bec20211ae706a7bd957ecda60ff051a5a15b836b543e&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Its principal source artifacts are &lt;code&gt;manifest.json&lt;/code&gt; (case/condition data), &lt;code&gt;prompts.jsonl&lt;/code&gt; (36 exact task prompts), &lt;code&gt;model_raw.jsonl&lt;/code&gt; (36 successful API responses plus a failure), &lt;code&gt;events.jsonl&lt;/code&gt; (37 starts and finishes), &lt;code&gt;report_gpt-4.1-mini.json&lt;/code&gt; (frozen-derived report), &lt;code&gt;evidence_inference_pilot_v1_1.py&lt;/code&gt; (generation and scoring code), &lt;code&gt;EXPERIMENT_PROTOCOL_v1_1.md&lt;/code&gt; (pre-run rules), and &lt;code&gt;DECISIONS_AND_DEVIATIONS.md&lt;/code&gt; (pre- and post-preflight decisions).&lt;/p&gt;

&lt;p&gt;The response archive and event hashes are respectively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;888d9e94b3e36379b175e51d7fcf602d1e31b0b15221026e09de9fc4aa897cab&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;983590dc9cb85d16cca78447d680a51311e8bbdb58663bb8e80d0e17e8a1631d&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A separately implemented, read-only Python standard-library script, &lt;code&gt;independent_audit_v1_1.py&lt;/code&gt;, verifies the recorded file hashes, reconstructs prompt texts and hashes, checks start/finish pairs and unique outcomes, recomputes strict and exploratory counts, and writes a 36-row matrix without modifying the original archive. With the files together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 independent_audit_v1_1.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--archive&lt;/span&gt; evidence_inference_results_v1_1.zip &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--out&lt;/span&gt; independent_audit_output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;derived_audit_v1_1.json&lt;/code&gt; and &lt;code&gt;trial_matrix_v1_1.csv&lt;/code&gt; are newly generated &lt;strong&gt;analysis artifacts&lt;/strong&gt;, not original experimental records. For any individual result, follow &lt;code&gt;trial_id + task&lt;/code&gt; in the matrix to its &lt;code&gt;attempt_id&lt;/code&gt;, &lt;code&gt;prompt_sha256&lt;/code&gt;, and provider response ID, then consult the exact entry in &lt;code&gt;prompts.jsonl&lt;/code&gt; and &lt;code&gt;model_raw.jsonl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Archival caveat:&lt;/strong&gt; The results ZIP flattens its paths. Its retained &lt;code&gt;SHA256SUMS.txt&lt;/code&gt; refers to an earlier pre-run &lt;code&gt;DECISIONS_AND_DEVIATIONS.md&lt;/code&gt;, whose hash appropriately changed when append-only decisions were recorded, as well as two initial-bundle files not included in the results ZIP (&lt;code&gt;README_CHROMEBOOK.md&lt;/code&gt; and an archived v1.0 script). The principal &lt;strong&gt;v1.1&lt;/strong&gt; protocol/script and generated prompt/raw files have been checked separately. Preserve the originally downloaded v1.1 bundle alongside the results ZIP for full historical documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix B — Origin links and review boundaries
&lt;/h2&gt;

&lt;p&gt;These are specific comments in the original DEV.to discussion, included so a reader can audit the research question without relying on my paraphrase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/gnomeman4201/comment/3j7d4"&gt;Initial composed-claim question&lt;/a&gt; — GnomeMan4201, October 27.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/rudratosh/comment/3j8ao"&gt;Acknowledgment of the claim-composition gap&lt;/a&gt; — Rudratosh, October 28.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/squeaky_spirit/comment/3jaca"&gt;Extractor idea and same-evidence ordering proposal&lt;/a&gt; — Squeaky, October 28.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/gnomeman4201/comment/3jbo7"&gt;Separating verdict stability from evidence support&lt;/a&gt; — GnomeMan4201, October 29.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/squeaky_spirit/comment/3jaol"&gt;External-standard / rival-inference objection&lt;/a&gt; — Squeaky, October 29.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/squeaky_spirit/comment/3jbof"&gt;Surviving alternatives versus prior-based ranking&lt;/a&gt; — Squeaky, October 29.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The article motivates a new self-conducted experiment; it does not claim these commenters performed, supervised, or reviewed it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public artifact:&lt;/strong&gt; &lt;a href="https://github.com/GnomeMan4201/composed-inference-ordering-v1.1/blob/main/Research_v1_1.zip" rel="noopener noreferrer"&gt;Research_v1_1.zip&lt;/a&gt; in the &lt;a href="https://github.com/GnomeMan4201/composed-inference-ordering-v1.1" rel="noopener noreferrer"&gt;public GitHub repository&lt;/a&gt;. The ZIP contains &lt;code&gt;materials/evidence_inference_results_v1_1.zip&lt;/code&gt;, the original unmodified archive (SHA-256 &lt;code&gt;b117050aa57dd573ac8bec20211ae706a7bd957ecda60ff051a5a15b836b543e&lt;/code&gt;), as well as &lt;code&gt;materials/independent_audit_v1_1.py&lt;/code&gt;, the trial matrix, and accompanying documentation. The publication ZIP SHA-256 is &lt;code&gt;598527528087ca10efdd09523c27f242861062d75e01432d0c4df377e8428c0e&lt;/code&gt;. After extracting &lt;code&gt;Research_v1_1.zip&lt;/code&gt;, run &lt;code&gt;python3 materials/independent_audit_v1_1.py --archive materials/evidence_inference_results_v1_1.zip --out independent_audit_output&lt;/code&gt; from the extracted directory. These reproducibility files do &lt;strong&gt;not&lt;/strong&gt; constitute independent adjudication of the labels or external replication.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>rag</category>
      <category>llm</category>
    </item>
    <item>
      <title>did I just spend the last few days having conversations across different DEV posts, only to suddenly wonder if I’ve been talking to AI agents this whole time? 

..... how would I even know anymore?</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Fri, 30 Oct 2026 05:13:00 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/did-i-just-spend-the-last-few-days-having-conversations-across-different-dev-posts-only-to-314</link>
      <guid>https://dev.to/gnomeman4201/did-i-just-spend-the-last-few-days-having-conversations-across-different-dev-posts-only-to-314</guid>
      <description></description>
      <category>discuss</category>
      <category>watercooler</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Notes on Archives and Honest Infrastructure Research</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sun, 18 Oct 2026 04:52:29 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/-unknown-is-not-zero-notes-on-archives-and-honest-infrastructure-research-g83</link>
      <guid>https://dev.to/gnomeman4201/-unknown-is-not-zero-notes-on-archives-and-honest-infrastructure-research-g83</guid>
      <description>&lt;p&gt;I’m working on UINET (Ukraine Influence Network Tracker) — a personal research project that’s still taking shape.&lt;/p&gt;

&lt;p&gt;October 2026 · Work in progress · Open to discussion&lt;/p&gt;

&lt;p&gt;I started working on UINET because I wanted to better understand how websites involved in documented online influence operations might be connected through their historical infrastructure. If two sites used the same server, tracking identifier, certificate, or backend service, could I establish when that overlap existed and what it actually meant?&lt;/p&gt;

&lt;p&gt;The further I got, the more that question changed. Now I spend as much time thinking about what the evidence cannot tell me as I do about what it can.&lt;/p&gt;

&lt;p&gt;I’m sharing these notes because I’d like to talk with people who have dealt with similar problems. The repository is private while I’m still working through the methods. I’m not announcing a finished tool, asking anyone to adopt it, or claiming to have identified an operator.&lt;/p&gt;

&lt;p&gt;An overlap isn’t an answer&lt;/p&gt;

&lt;p&gt;Two websites sharing an IP address doesn’t necessarily mean they have the same operator. They could use common hosting or a CDN. Two sites sharing an analytics identifier might have copied the same legitimate website’s code. A matching backend hostname can be worth investigating without being evidence of common control.&lt;/p&gt;

&lt;p&gt;What I’m trying to build is a way to keep the observation, its source, and the interpretation separate. Rather than outputting a confident looking connection, I’d rather have a record that says: Here is what matched, here is when it was observed, here is the archived evidence, and here are the explanations that are still possible.&lt;/p&gt;

&lt;p&gt;Historical archives make this harder. If a page isn’t available, I can’t conclude that it lacked a tracking tag. Maybe it was never captured. Maybe the index query was incomplete. Maybe the archive returned an error, or a capture exists but can’t be retrieved or inspected. Those are different kinds of uncertainty.&lt;/p&gt;

&lt;p&gt;The rule I keep coming back to is simple: UNKNOWN is not zero. A failed lookup isn’t proof of absence, and a page I couldn’t examine isn’t a negative inspection.&lt;/p&gt;

&lt;p&gt;Making interrupted research visible&lt;/p&gt;

&lt;p&gt;Some of the least glamorous work has also been the most useful. I’m building an append only journal for the collection process so that a request is recorded as started before it is made, raw responses can be checked against hashes, and interrupted attempts don’t disappear on restart.&lt;/p&gt;

&lt;p&gt;If a process stops halfway through a request, it doesn’t get a free extra try. The attempt remains spent, and the outcome can remain UNKNOWN. Otherwise a collector might quietly retry until it gets a convenient answer, making the final data look cleaner than the process really was.&lt;/p&gt;

&lt;p&gt;In a Linux Codespace, I tested recovery by deliberately killing child processes with SIGKILL at several storage boundaries, including during a temporary raw response write and during journal recovery. Those offline tests passed. That tells me the specific recovery paths behaved as intended in that environment; it doesn’t establish power-loss durability, perfect evidence custody, or the accuracy of any real world investigation.&lt;/p&gt;

&lt;p&gt;Most of this project has been managed from my iPhone. Moving those particular tests to a Linux Codespace was a practical reminder that the claim should match the environment actually tested, not the one I wish had worked.&lt;/p&gt;

&lt;p&gt;Why I’m spending time with old archives&lt;/p&gt;

&lt;p&gt;I’m planning a limited feasibility study of 83 distinct historical domain names drawn from two public documentary source frames: EU DisinfoLab’s September 2022 Doppelganger investigation and the U.S. Department of Justice’s September 2024 Doppelganger affidavit. The set has 56 mentions in the first frame and 32 in the second, with five names appearing in both. That overlap in reports isn’t independent evidence of operator continuity.&lt;/p&gt;

&lt;p&gt;I’ve also been learning from VIGINUM’s February 2024 Portal Kombat report. Portal Kombat is separate from the 83 name Doppelganger feasibility set; I’m mentioning it as related research, not mixing its sites into that inventory.&lt;/p&gt;

&lt;p&gt;For the proposed first pass, I want to ask a modest question: is enough dated archive index metadata available to justify attempting deeper historical analysis? Finding an indexed capture would not yet mean I could retrieve and inspect the original HTML or JavaScript.&lt;/p&gt;

&lt;p&gt;I have draft coverage thresholds, but they’re not approved or fully justified yet. Two objections have been especially useful. A fixed 1,000 row response cap might label the best archived domains incomplete, while one request per domain might turn a transient archive outage into apparent historical missingness. I’m considering bounded pagination or filtering and a finite, explicitly recorded retry budget. I haven’t adopted those changes or run the live census.&lt;/p&gt;

&lt;p&gt;If the archive doesn’t provide adequate evidence, reporting that limitation could be the outcome. I don’t want to quietly swap difficult domains for easier ones just to make the results look complete.&lt;/p&gt;

&lt;p&gt;A disagreement I’m glad I didn’t erase&lt;/p&gt;

&lt;p&gt;An earlier AI assisted adversarial review produced agreement with the classifier on six of eight primary synthetic cases. Two disagreements made me rethink how the rules were written. The examples below are fictional illustrations, not observations about real websites.&lt;/p&gt;

&lt;p&gt;Imagine two impersonation sites, harbor copy.test and valley copy.test, whose archived pages on October 12, 2023 both include a tag shaped like GTM EXAMPLE1. Now imagine the genuine outlet’s archived page from October 11, 2023 contains that same tag. I might initially see a shared tracking identifier between the two impersonation sites, but the genuine page gives me a plausible copied code explanation. If that is the only shared artifact, what positive evidence remains for common control? For me, the right move is to exclude that tag as operator evidence not to invent another connection because the sites look suspicious.&lt;/p&gt;

&lt;p&gt;The other disagreement involved a shared backend hostname and incomplete coverage of legitimate reference sites. I’m leaning toward a firmer rule here: missing reference evidence can limit confidence, but it cannot make a weak signal stronger. If I haven’t checked the necessary historical pages, I can’t treat their silence as proof that the backend was unique to the suspicious sites.&lt;/p&gt;

&lt;p&gt;A later discussion of those cases involved me and AI assistance and was not blind or independent re-adjudication. The original 6/8 result stays in the record. I’m much more interested in getting the rule clear than in retroactively turning a disagreement into a pass.&lt;/p&gt;

&lt;p&gt;What I’d like to hear from others&lt;/p&gt;

&lt;p&gt;I’m still thinking about how people handle the boundary between what wasn’t found and what couldn’t be checked. For those who work with archived web data: how do you design a coverage measure that doesn’t punish well archived sites when query limits are hit? What retry budget feels reproducible without being unfriendly to public archives? And when you’ve seen genuine site code copied onto a lookalike, what evidence would persuade you that a remaining technical overlap is meaningful?&lt;/p&gt;

&lt;p&gt;I’d also be interested in how small research projects preserve collection logs and hashes without overstating what a timestamp or a chain of hashes proves.&lt;/p&gt;

&lt;p&gt;I don’t yet know whether the historical material will support the question I started with. If it doesn’t, that’s worth understanding too. I’m working on the methods, finding the weak spots, and sharing them because the discussion may be more useful than pretending I’ve already solved them.&lt;/p&gt;

&lt;p&gt;────────&lt;/p&gt;

&lt;p&gt;Public background reading&lt;/p&gt;

&lt;p&gt;• EU DisinfoLab (September 27, 2022): Doppelganger — Media clones serving Russian propaganda&lt;br&gt;
• U.S. Department of Justice (September 4, 2024): Affidavit in support of seizure warrant, Case 2:24-mj-01395 (PDF)&lt;br&gt;
• VIGINUM / SGDSN (February 12, 2024): Portal Kombat — A structured and coordinated pro-Russian propaganda network&lt;/p&gt;

&lt;p&gt;These sources document the context for my research. They are not independent validation of UINET or its current classification results. No live historical domain census has been run for this progress note.&lt;/p&gt;

</description>
      <category>osint</category>
      <category>cybersecurity</category>
      <category>discuss</category>
      <category>opensource</category>
    </item>
    <item>
      <title>R4B1T_H0LE: DESCENT</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Wed, 16 Sep 2026 03:50:45 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/r4b1th0le-descent-3aik</link>
      <guid>https://dev.to/gnomeman4201/r4b1th0le-descent-3aik</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rcqkjeguoylccwgi6bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rcqkjeguoylccwgi6bh.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first time I wrote about &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt;, I was mostly interested in whether the idea itself worked.&lt;/p&gt;

&lt;p&gt;Could I take a large curated pool of useful corners of the internet, remove the search box, remove the recommendation profile, remove the ranking layer, and make discovery feel unpredictable again?&lt;/p&gt;

&lt;p&gt;That part worked.&lt;/p&gt;

&lt;p&gt;What I did not expect was how much the project would start changing the way I think about software.&lt;/p&gt;

&lt;p&gt;Not just the backend.&lt;/p&gt;

&lt;p&gt;Not just security.&lt;/p&gt;

&lt;p&gt;The frontend too.&lt;/p&gt;

&lt;p&gt;And maybe more than anything else, the space where code, mechanics, motion, and art start overlapping.&lt;/p&gt;

&lt;p&gt;This is not an "I learned frontend" post.&lt;/p&gt;

&lt;p&gt;If anything, &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; has done the opposite for me.&lt;/p&gt;

&lt;p&gt;It opened another door and showed me how much more there is to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  One of a handful of developers who changed how I think about building
&lt;/h2&gt;

&lt;p&gt;This shift did not happen in isolation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/nyaomaru"&gt;&lt;strong&gt;nyaomaru&lt;/strong&gt;&lt;/a&gt; is one of a small number of developers whose work has genuinely shaped the way I think about interfaces.&lt;/p&gt;

&lt;p&gt;Their work has such a recognizable personality that you can almost tell who built it before you ever read the name.&lt;/p&gt;

&lt;p&gt;And it is not just visual.&lt;/p&gt;

&lt;p&gt;It is the way their interfaces move. The way controls respond. The way transitions feel. The way mechanics and presentation seem to belong to the same system instead of one being added after the other.&lt;/p&gt;

&lt;p&gt;What stood out to me was never one particular design trend or effect.&lt;/p&gt;

&lt;p&gt;It was seeing an interface that felt unmistakably like it had been made by a particular person.&lt;/p&gt;

&lt;p&gt;Not a template.&lt;/p&gt;

&lt;p&gt;Not "good UI" in some generic sense.&lt;/p&gt;

&lt;p&gt;Something with a point of view.&lt;/p&gt;

&lt;p&gt;I am not trying to reproduce anybody else's style.&lt;/p&gt;

&lt;p&gt;If anything, seeing a developer build interfaces that felt unmistakably theirs made me start wondering what &lt;strong&gt;mine&lt;/strong&gt; could look like.&lt;/p&gt;

&lt;p&gt;If you ever get the chance, I highly recommend taking a look at &lt;a href="https://dev.to/nyaomaru"&gt;nyaomaru's work&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; actually is
&lt;/h2&gt;

&lt;p&gt;I think it is important to keep being clear about this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; is not a search engine.&lt;/p&gt;

&lt;p&gt;It does not crawl the entire internet.&lt;/p&gt;

&lt;p&gt;It does not know whether every page in the corpus is good, correct, safe, or useful.&lt;/p&gt;

&lt;p&gt;SPROUT is not some all-knowing AI recommendation system.&lt;/p&gt;

&lt;p&gt;A URL being structurally valid does not mean that URL is currently alive.&lt;/p&gt;

&lt;p&gt;A network request failing does not automatically mean a resource deserves to be deleted.&lt;/p&gt;

&lt;p&gt;And the project is not finished.&lt;/p&gt;

&lt;p&gt;What &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; is, right now, is a curated discovery experiment.&lt;/p&gt;

&lt;p&gt;A large corpus.&lt;/p&gt;

&lt;p&gt;A chance-driven route through it.&lt;/p&gt;

&lt;p&gt;A set of controls for deciding where to go next.&lt;/p&gt;

&lt;p&gt;A local trail that records where you went.&lt;/p&gt;

&lt;p&gt;A growing attempt to make those mechanics understandable, deliberate, secure, and eventually verifiable.&lt;/p&gt;

&lt;p&gt;The current frozen structural baseline is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;50,109&lt;/strong&gt; structurally valid URLs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12,396&lt;/strong&gt; unique hosts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt; invalid, duplicate, or credential-bearing entries admitted into that audited baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is what the evidence supports.&lt;/p&gt;

&lt;p&gt;It does not prove anything stronger than that.&lt;/p&gt;

&lt;p&gt;I care about keeping that distinction intact.&lt;/p&gt;

&lt;h2&gt;
  
  
  I came into this from the other side of the screen
&lt;/h2&gt;

&lt;p&gt;Most of my comfort zone has always been behind the interface.&lt;/p&gt;

&lt;p&gt;Terminals.&lt;/p&gt;

&lt;p&gt;Scripts.&lt;/p&gt;

&lt;p&gt;Networking.&lt;/p&gt;

&lt;p&gt;Requests.&lt;/p&gt;

&lt;p&gt;Databases.&lt;/p&gt;

&lt;p&gt;Automation.&lt;/p&gt;

&lt;p&gt;Security boundaries.&lt;/p&gt;

&lt;p&gt;Logs.&lt;/p&gt;

&lt;p&gt;Evidence.&lt;/p&gt;

&lt;p&gt;Things where the important question is usually:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did the system behave correctly?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Give me an ugly backend problem and I am usually much more comfortable than if you ask me why one transition feels better than another.&lt;/p&gt;

&lt;p&gt;That started changing with &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At first, frontend was mostly the part I needed so people could use the thing.&lt;/p&gt;

&lt;p&gt;Then I started noticing details.&lt;/p&gt;

&lt;p&gt;Then I started caring about them.&lt;/p&gt;

&lt;p&gt;Then I started spending ridiculous amounts of time on them.&lt;/p&gt;

&lt;p&gt;And somewhere in there, frontend stopped feeling like the layer I put on top of the "real" work.&lt;/p&gt;

&lt;p&gt;It became another kind of engineering problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  I did not learn frontend
&lt;/h2&gt;

&lt;p&gt;I started learning how big frontend actually is.&lt;/p&gt;

&lt;p&gt;That is different.&lt;/p&gt;

&lt;p&gt;Backend and security already taught me this lesson.&lt;/p&gt;

&lt;p&gt;You enter a field thinking it is one thing.&lt;/p&gt;

&lt;p&gt;Then you get far enough into it to realize it is actually hundreds of smaller disciplines stacked together.&lt;/p&gt;

&lt;p&gt;Frontend is starting to feel the same way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Motion design.&lt;/li&gt;
&lt;li&gt;Typography.&lt;/li&gt;
&lt;li&gt;Responsive behavior.&lt;/li&gt;
&lt;li&gt;Accessibility.&lt;/li&gt;
&lt;li&gt;Perceived performance.&lt;/li&gt;
&lt;li&gt;Browser behavior.&lt;/li&gt;
&lt;li&gt;State communication.&lt;/li&gt;
&lt;li&gt;Visual hierarchy.&lt;/li&gt;
&lt;li&gt;Interaction design.&lt;/li&gt;
&lt;li&gt;Spacing.&lt;/li&gt;
&lt;li&gt;Color.&lt;/li&gt;
&lt;li&gt;Animation timing.&lt;/li&gt;
&lt;li&gt;Rendering.&lt;/li&gt;
&lt;li&gt;Focus behavior.&lt;/li&gt;
&lt;li&gt;Touch targets.&lt;/li&gt;
&lt;li&gt;Keyboard navigation.&lt;/li&gt;
&lt;li&gt;Mobile ergonomics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is just the part I can currently see.&lt;/p&gt;

&lt;p&gt;I have learned enough to understand how much I do not know yet.&lt;/p&gt;

&lt;p&gt;That is not discouraging to me.&lt;/p&gt;

&lt;p&gt;That is the interesting part.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; exists because I like finding things I did not know to search for.&lt;/p&gt;

&lt;p&gt;Learning frontend has started to feel strangely similar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;discover something unexpected
  ↓
follow it
  ↓
branch
  ↓
find something else you did not know existed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;learning frontend&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solve one interface problem
  ↓
discover motion systems
  ↓
discover accessibility
  ↓
discover responsive behavior
  ↓
discover browser quirks
  ↓
keep going
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not a finished chapter.&lt;/p&gt;

&lt;p&gt;It is a new page in a book that suddenly got much bigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  When code became a medium
&lt;/h2&gt;

&lt;p&gt;This might be the part I expected the least.&lt;/p&gt;

&lt;p&gt;I have always used code to solve problems.&lt;/p&gt;

&lt;p&gt;Frontend gave me another way to use it.&lt;/p&gt;

&lt;p&gt;A way to express something.&lt;/p&gt;

&lt;p&gt;Color.&lt;/p&gt;

&lt;p&gt;Typography.&lt;/p&gt;

&lt;p&gt;Spacing.&lt;/p&gt;

&lt;p&gt;Timing.&lt;/p&gt;

&lt;p&gt;Motion.&lt;/p&gt;

&lt;p&gt;The way something enters the screen.&lt;/p&gt;

&lt;p&gt;The way it leaves.&lt;/p&gt;

&lt;p&gt;The amount of information you expose at once.&lt;/p&gt;

&lt;p&gt;The way a control reacts when you touch it.&lt;/p&gt;

&lt;p&gt;The way one state turns into another.&lt;/p&gt;

&lt;p&gt;Those decisions can carry personality.&lt;/p&gt;

&lt;p&gt;At some point, &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; stopped feeling like an interface I was decorating.&lt;/p&gt;

&lt;p&gt;It started feeling more like something I was composing.&lt;/p&gt;

&lt;p&gt;The backend still matters.&lt;/p&gt;

&lt;p&gt;The data still matters.&lt;/p&gt;

&lt;p&gt;The security boundaries still matter.&lt;/p&gt;

&lt;p&gt;But there is another layer now where code and art overlap.&lt;/p&gt;

&lt;p&gt;And I did not really understand how powerful that could be until I started trying to make it work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Frontend gave my code handwriting.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am still figuring out what that handwriting looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhn59g1ci1d3epwlnsmte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhn59g1ci1d3epwlnsmte.png" alt=" " width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motion is not decoration anymore
&lt;/h2&gt;

&lt;p&gt;Early on, I thought about animation mostly in terms of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this look cool?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That changed.&lt;/p&gt;

&lt;p&gt;Now I think more about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is this motion communicating?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A route appearing should not feel the same as a branch opening.&lt;/p&gt;

&lt;p&gt;A rejection should not feel the same as following something.&lt;/p&gt;

&lt;p&gt;A first-time visitor should not be hit with instrumentation before they understand what the tool is.&lt;/p&gt;

&lt;p&gt;A trail should feel like something accumulating.&lt;/p&gt;

&lt;p&gt;A transition should help the eye understand where the interface went.&lt;/p&gt;

&lt;p&gt;If everything moves, nothing has emphasis.&lt;/p&gt;

&lt;p&gt;If movement takes too long, the interface feels slow even if the code is fast.&lt;/p&gt;

&lt;p&gt;If two elements use completely different timing, the application starts feeling assembled instead of intentional.&lt;/p&gt;

&lt;p&gt;If animation is required to understand state, reduced-motion behavior becomes part of correctness — not an afterthought.&lt;/p&gt;

&lt;p&gt;That is where the project started moving away from "adding animations" and toward something closer to a motion system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROLL
  ↓
current route yields
  ↓
new state begins
  ↓
route enters
  ↓
supporting instrumentation follows
  ↓
interface settles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those tiny details are some of the most time-consuming things I have worked on lately.&lt;/p&gt;

&lt;p&gt;And they are also some of the most satisfying.&lt;/p&gt;

&lt;p&gt;Because once you notice them, you cannot really stop noticing them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7u3nczmv58o5b9hwgqpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7u3nczmv58o5b9hwgqpe.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile taught me another lesson
&lt;/h2&gt;

&lt;p&gt;Shrinking desktop until it fits on a phone is not mobile design.&lt;/p&gt;

&lt;p&gt;That seems obvious when I write it.&lt;/p&gt;

&lt;p&gt;It was less obvious when I was actually building it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; now has two shells around the same engine.&lt;/p&gt;

&lt;p&gt;The workstation version can afford context.&lt;/p&gt;

&lt;p&gt;More topology.&lt;/p&gt;

&lt;p&gt;More history.&lt;/p&gt;

&lt;p&gt;More controls.&lt;/p&gt;

&lt;p&gt;More simultaneous information.&lt;/p&gt;

&lt;p&gt;Mobile has to make harder choices.&lt;/p&gt;

&lt;p&gt;What matters first?&lt;/p&gt;

&lt;p&gt;What can wait?&lt;/p&gt;

&lt;p&gt;What is reachable with a thumb?&lt;/p&gt;

&lt;p&gt;What can be hidden without becoming confusing?&lt;/p&gt;

&lt;p&gt;What needs motion to preserve continuity?&lt;/p&gt;

&lt;p&gt;What should disappear completely?&lt;/p&gt;

&lt;p&gt;Same engine.&lt;/p&gt;

&lt;p&gt;Same corpus.&lt;/p&gt;

&lt;p&gt;Same underlying state.&lt;/p&gt;

&lt;p&gt;Different experience.&lt;/p&gt;

&lt;p&gt;That distinction has been one of the most useful frontend lessons in the project so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  The security part never went away
&lt;/h2&gt;

&lt;p&gt;The funny thing is that learning frontend did not pull me away from the parts of software I already care about.&lt;/p&gt;

&lt;p&gt;It made them more important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; deals with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;external URLs&lt;/li&gt;
&lt;li&gt;external metadata&lt;/li&gt;
&lt;li&gt;external redirects&lt;/li&gt;
&lt;li&gt;a service worker&lt;/li&gt;
&lt;li&gt;local session state&lt;/li&gt;
&lt;li&gt;optional proxy behavior&lt;/li&gt;
&lt;li&gt;a large changing corpus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives a random discovery tool a surprisingly strange threat model.&lt;/p&gt;

&lt;p&gt;The more polished the interface becomes, the easier it would be to forget that much of what it displays comes from systems I do not control.&lt;/p&gt;

&lt;p&gt;So I keep coming back to the habits I already trust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;do not trust input&lt;/li&gt;
&lt;li&gt;do not confuse an observation with a fact&lt;/li&gt;
&lt;li&gt;do not give automation more authority than it needs&lt;/li&gt;
&lt;li&gt;do not give CI write permission just because it is convenient&lt;/li&gt;
&lt;li&gt;do not let one network failure become a permanent corpus decision&lt;/li&gt;
&lt;li&gt;do not pretend external content is safe because it appeared inside a nice interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That mindset changed the repository too.&lt;/p&gt;

&lt;p&gt;The current sweep workflow does not get to rewrite the corpus.&lt;/p&gt;

&lt;p&gt;It observes.&lt;/p&gt;

&lt;p&gt;It records.&lt;/p&gt;

&lt;p&gt;It hashes the input.&lt;/p&gt;

&lt;p&gt;It separates reachable, missing, and indeterminate results.&lt;/p&gt;

&lt;p&gt;It produces evidence for review.&lt;/p&gt;

&lt;p&gt;It does not get deletion authority.&lt;/p&gt;

&lt;p&gt;That distinction became important enough that I started thinking about it as a general rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Observation is not authority.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That applies to more than dead links.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed underneath the sweep
&lt;/h2&gt;

&lt;p&gt;One of the more technical examples of that ongoing cleanup is the URL observation system.&lt;/p&gt;

&lt;p&gt;The current implementation has moved beyond several of its earlier weaknesses.&lt;/p&gt;

&lt;p&gt;It now includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bounded HEAD → GET fallback for specific rejection statuses&lt;/li&gt;
&lt;li&gt;explicit handling for confirmed missing responses&lt;/li&gt;
&lt;li&gt;per-thread HTTP sessions instead of sharing one session across workers&lt;/li&gt;
&lt;li&gt;redirect handling without blindly following chains&lt;/li&gt;
&lt;li&gt;target guards for private or otherwise disallowed destinations&lt;/li&gt;
&lt;li&gt;offline deterministic HTTP behavior tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not a flashy frontend feature.&lt;/p&gt;

&lt;p&gt;But it is part of the same project.&lt;/p&gt;

&lt;p&gt;The interface, motion system, corpus policy, tests, security boundaries, and deployment are not separate projects.&lt;/p&gt;

&lt;p&gt;They are different layers of the same one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The repository had to grow up too
&lt;/h2&gt;

&lt;p&gt;At one point I looked at the project and realized something uncomfortable.&lt;/p&gt;

&lt;p&gt;The application had grown much faster than the public repository around it.&lt;/p&gt;

&lt;p&gt;There were old screenshots.&lt;/p&gt;

&lt;p&gt;One-off patch scripts.&lt;/p&gt;

&lt;p&gt;Old experiments.&lt;/p&gt;

&lt;p&gt;Branches from ideas that had already been merged or abandoned.&lt;/p&gt;

&lt;p&gt;Historical tooling that no longer represented the current architecture.&lt;/p&gt;

&lt;p&gt;All of that had been useful at some point.&lt;/p&gt;

&lt;p&gt;That did not mean it still belonged in the public surface.&lt;/p&gt;

&lt;p&gt;So part of this overhaul was subtraction.&lt;/p&gt;

&lt;p&gt;A lot of subtraction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEFORE
  dozens of development branches
  old patch scripts
  legacy screenshots
  older demo assets
  historical experiments
  current application

AFTER
  main
  gh-pages
  maintained tooling
  documented architecture
  current visual assets
  tests
  evidence workflows
  current application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository currently has only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main
gh-pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That cleanup probably does not make &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; look any different when you press ROLL.&lt;/p&gt;

&lt;p&gt;But it makes the project easier to understand.&lt;/p&gt;

&lt;p&gt;And that matters.&lt;/p&gt;

&lt;p&gt;A public repository tells two stories.&lt;/p&gt;

&lt;p&gt;One is the software you want people to use.&lt;/p&gt;

&lt;p&gt;The other is every abandoned way you once tried to build it.&lt;/p&gt;

&lt;p&gt;At some point, those stories needed separating.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring parts became part of the product
&lt;/h2&gt;

&lt;p&gt;I used to think of things like issue templates, test paths, contribution guidance, deployment workflows, and security reporting as repository administration.&lt;/p&gt;

&lt;p&gt;I do not really see them that way anymore.&lt;/p&gt;

&lt;p&gt;They are part of whether the project can survive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; now has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured bug reports&lt;/li&gt;
&lt;li&gt;structured URL submissions&lt;/li&gt;
&lt;li&gt;a pull request verification checklist&lt;/li&gt;
&lt;li&gt;private vulnerability reporting guidance&lt;/li&gt;
&lt;li&gt;stronger ignore rules&lt;/li&gt;
&lt;li&gt;deterministic corpus checks&lt;/li&gt;
&lt;li&gt;browser regression tests&lt;/li&gt;
&lt;li&gt;local and CI path alignment&lt;/li&gt;
&lt;li&gt;report-only network sweeps&lt;/li&gt;
&lt;li&gt;a much smaller deployment workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that changes what happens when someone presses ROLL.&lt;/p&gt;

&lt;p&gt;It changes whether I can understand what happened when ROLL breaks six months from now.&lt;/p&gt;

&lt;p&gt;That is a different kind of polish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things that are still unfinished
&lt;/h2&gt;

&lt;p&gt;This is the part I do not want to hide.&lt;/p&gt;

&lt;p&gt;The project still has rough edges.&lt;/p&gt;

&lt;p&gt;The formal release history is behind the actual implementation.&lt;/p&gt;

&lt;p&gt;The package identifies itself as 1.1.0, while the latest GitHub Release is still v1.0.0.&lt;/p&gt;

&lt;p&gt;Some older documentation still describes limitations that have already been fixed in the current sweep engine.&lt;/p&gt;

&lt;p&gt;The repository homepage metadata still needs to be brought fully in line with the current project site.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main&lt;/code&gt; is not currently protected by an enforced branch rule.&lt;/p&gt;

&lt;p&gt;The corpus will always need maintenance because the internet underneath it keeps changing.&lt;/p&gt;

&lt;p&gt;And I am sure there are frontend decisions I am making right now that I will look back on later and want to redo.&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;

&lt;p&gt;That means the project is still alive.&lt;/p&gt;

&lt;p&gt;And it means I am still learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; becoming?
&lt;/h2&gt;

&lt;p&gt;I do not have a perfect answer.&lt;/p&gt;

&lt;p&gt;That is probably why I want to keep writing these.&lt;/p&gt;

&lt;p&gt;It started as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;random discovery for a niche corner of the internet&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then it became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;how do I make random discovery useful?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;how do I preserve where somebody went?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;how do I prove something about that trail without claiming more than the evidence supports?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;how should this feel on a phone?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;why does this transition feel wrong?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;why should a failed network request have the authority to delete anything?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;what does my own visual style actually look like?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The rabbit hole metaphor is starting to become annoyingly accurate.&lt;/p&gt;

&lt;p&gt;Every answer opens another branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new page, not a finished chapter
&lt;/h2&gt;

&lt;p&gt;I am still much more comfortable in a terminal than I am designing an interface.&lt;/p&gt;

&lt;p&gt;That has not changed.&lt;/p&gt;

&lt;p&gt;What has changed is that I no longer see frontend as the shallow side of the stack.&lt;/p&gt;

&lt;p&gt;It is another enormous technical field.&lt;/p&gt;

&lt;p&gt;And beyond that, it is a medium.&lt;/p&gt;

&lt;p&gt;A place where logic and mechanics can carry personality.&lt;/p&gt;

&lt;p&gt;Where code can become visual.&lt;/p&gt;

&lt;p&gt;Where engineering decisions can also become artistic decisions.&lt;/p&gt;

&lt;p&gt;Where a system can communicate before anybody reads the documentation.&lt;/p&gt;

&lt;p&gt;I have barely started exploring that.&lt;/p&gt;

&lt;p&gt;That is exactly why I want to keep going.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;&lt;strong&gt;r4b1t_h0le&lt;/strong&gt;&lt;/a&gt; started as a project about discovering things I did not know to look for.&lt;br&gt;&lt;br&gt;
Somewhere along the way, frontend became one of them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Current state
&lt;/h2&gt;

&lt;p&gt;At the time of writing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current frozen corpus baseline: &lt;strong&gt;50,109 structurally valid URLs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;12,396 unique hosts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;repository branches: &lt;strong&gt;main + gh-pages&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;current package version: &lt;strong&gt;1.1.0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;current browser tests: &lt;strong&gt;passing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;current Pages deployment: &lt;strong&gt;passing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;pool sweep: &lt;strong&gt;report-only&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;trails: &lt;strong&gt;device-local&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;architecture: &lt;strong&gt;still framework-light&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;frontend knowledge: &lt;strong&gt;very much still in progress&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is probably the most important line in the list. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs6o8w5noivp5s6e1n9mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs6o8w5noivp5s6e1n9mg.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project:&lt;/strong&gt; &lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;r4b1t_h0le&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/GnomeMan4201/r4b1t" rel="noopener noreferrer"&gt;GnomeMan4201/r4b1t&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Original write-up:&lt;/strong&gt; &lt;a href="https://dev.to/gnomeman4201/r4b1th0l3-5aa3"&gt;r4b1t_h0le — 53,000+ curated links for security and OSINT&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;r4b1t_h0le&lt;/a&gt; // DESCENT LOG 01&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;badBANANA Research Collective&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>opensource</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Kept Getting Strange GitHub Followers...so i looked into it</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sat, 05 Sep 2026 02:11:58 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/kept-getting-strange-github-followers-so-i-measured-them-3fac</link>
      <guid>https://dev.to/gnomeman4201/kept-getting-strange-github-followers-so-i-measured-them-3fac</guid>
      <description>&lt;p&gt;Over the past several weeks, I kept seeing something unusual in my GitHub followers.&lt;/p&gt;

&lt;p&gt;Not one suspicious account.&lt;/p&gt;

&lt;p&gt;Not even one suspicious batch.&lt;/p&gt;

&lt;p&gt;Repeated waves of accounts would appear with remarkably similar characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dozens of newly generated repositories&lt;/li&gt;
&lt;li&gt;thousands of outbound follows&lt;/li&gt;
&lt;li&gt;rapidly increasing follower counts&lt;/li&gt;
&lt;li&gt;similar repository structures&lt;/li&gt;
&lt;li&gt;similar commit histories&lt;/li&gt;
&lt;li&gt;synchronized changes in account behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any one of those characteristics can have a mundane explanation.&lt;/p&gt;

&lt;p&gt;Together, they were worth measuring.&lt;/p&gt;

&lt;p&gt;So instead of trying to decide whether the accounts “looked fake,” I started treating the activity as an evidence problem.&lt;/p&gt;

&lt;p&gt;The result became &lt;strong&gt;CF-GH-FOLLOW-02&lt;/strong&gt;, a public-only longitudinal investigation into what increasingly appears to be a repeatable GitHub account-development workflow.&lt;/p&gt;

&lt;p&gt;This post documents what I can establish from public evidence, what I can reasonably infer, and—equally important—what I cannot prove.&lt;/p&gt;




&lt;h2&gt;
  
  
  The first rule: don’t investigate the person
&lt;/h2&gt;

&lt;p&gt;The objective was never to identify whoever might be behind these accounts.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;A GitHub username, commit author name, email address, profile picture, company field, or location is not automatically a verified identity.&lt;/p&gt;

&lt;p&gt;The investigation therefore separates four different things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observation&lt;/strong&gt; — what the public evidence directly shows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inference&lt;/strong&gt; — what explanation best fits those observations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Campaign/workflow linkage&lt;/strong&gt; — whether separate accounts appear to participate in the same technical process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-person attribution&lt;/strong&gt; — who actually operates that process.&lt;/p&gt;

&lt;p&gt;The first three can sometimes be investigated from public evidence.&lt;/p&gt;

&lt;p&gt;The fourth remains unresolved here.&lt;/p&gt;




&lt;h2&gt;
  
  
  August 26: five accounts arrive
&lt;/h2&gt;

&lt;p&gt;The investigation began with five accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;alberto4442&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lxl0825&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fuad403273&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hassenbrahim&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Belucking&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At collection time, they each exposed approximately 59–60 public repositories.&lt;/p&gt;

&lt;p&gt;Their outbound-following counts were already enormous:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Account&lt;/th&gt;
&lt;th&gt;Following&lt;/th&gt;
&lt;th&gt;Public repos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alberto4442&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,380&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lxl0825&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,380&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fuad403273&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,381&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hassenbrahim&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,381&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Belucking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,695&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The repository portfolios were even more interesting.&lt;/p&gt;

&lt;p&gt;Across the five accounts there were 299 repositories, with essentially the entire visible portfolio generated inside a narrow window.&lt;/p&gt;

&lt;p&gt;Median intervals between repository creation events were roughly 340–346 seconds.&lt;/p&gt;

&lt;p&gt;Three accounts had identical programming-language sequences across all 59 comparable repository positions.&lt;/p&gt;

&lt;p&gt;The first 100 accounts followed by all five were also identical.&lt;/p&gt;

&lt;p&gt;For all ten account pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jaccard similarity = 1.000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That was enough to reject the idea that I was simply looking at five unrelated developers who happened to follow me around the same time.&lt;/p&gt;

&lt;p&gt;But it still wasn’t the strongest evidence.&lt;/p&gt;


&lt;h2&gt;
  
  
  The artifact that connected the accounts
&lt;/h2&gt;

&lt;p&gt;I sampled repository histories from each account.&lt;/p&gt;

&lt;p&gt;Every sampled history contained the same commit trailer:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Co-authored-by: nancodero &amp;lt;nancodero@proton.me&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The repositories also repeatedly used the same merge grammar:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merged PR #1
Automatically merged pull request #1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And the same pull-request structure:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initial Setup and Codebase for &amp;lt;repository&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;with bodies following the pattern:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This PR contains the initial setup, code implementation, and configuration for &amp;lt;repository&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That is much more useful than profile similarity.&lt;/p&gt;

&lt;p&gt;Profiles are easy to copy.&lt;/p&gt;

&lt;p&gt;Commit-history artifacts describe how repositories were actually produced.&lt;/p&gt;

&lt;p&gt;Then the templates started leaking information across account boundaries.&lt;/p&gt;

&lt;p&gt;Sampled READMEs belonging to different owners contained hard-coded references to another cohort account.&lt;/p&gt;

&lt;p&gt;Later generations produced similar leakage involving unrelated displayed personas and author identities.&lt;/p&gt;

&lt;p&gt;This strongly suggested that the visible profiles and the repository-generation process were separate layers.&lt;/p&gt;


&lt;h2&gt;
  
  
  Then an older investigation suddenly became relevant
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;nancodero&lt;/code&gt; trailer was not new.&lt;/p&gt;

&lt;p&gt;A previous August 9–10 follower wave had already exposed six repository owners associated with the same artifact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RashidSaeedAlMazrouei18&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ElvinHasanov3d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;badiranssen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Seo-yeonLee&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;KevinWong455&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;9Michael-Cooley&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those accounts had originally appeared during another unusual follower burst.&lt;/p&gt;

&lt;p&gt;Their repository histories contained the same:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nancodero &amp;lt;nancodero@proton.me&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;artifact.&lt;/p&gt;

&lt;p&gt;That changed the unit of analysis.&lt;/p&gt;

&lt;p&gt;The August 26 accounts were no longer just one strange five-account cluster.&lt;/p&gt;

&lt;p&gt;They were another generation of a workflow already observed weeks earlier.&lt;/p&gt;


&lt;h2&gt;
  
  
  Four older accounts disappeared
&lt;/h2&gt;

&lt;p&gt;When I returned to the six earlier accounts on August 27, four returned HTTP 404:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Account&lt;/th&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Followers&lt;/th&gt;
&lt;th&gt;Following&lt;/th&gt;
&lt;th&gt;Repos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ElvinHasanov3d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Seo-yeonLee&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Live&lt;/td&gt;
&lt;td&gt;1,024&lt;/td&gt;
&lt;td&gt;899&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;KevinWong455&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;9Michael-Cooley&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Live&lt;/td&gt;
&lt;td&gt;1,021&lt;/td&gt;
&lt;td&gt;893&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RashidSaeedAlMazrouei18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;badiranssen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A 404 does not tell me why an account disappeared.&lt;/p&gt;

&lt;p&gt;Deletion, suspension, rename, or another visibility change can produce similar observations.&lt;/p&gt;

&lt;p&gt;So I recorded exactly what the evidence established:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four previously observed usernames no longer resolved publicly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nothing more.&lt;/p&gt;

&lt;p&gt;But the two surviving accounts had converged on another interesting state: roughly 1,020 followers, 895 following, and 51–53 repositories.&lt;/p&gt;

&lt;p&gt;That looked very different from the newer accounts with thousands of outbound follows.&lt;/p&gt;

&lt;p&gt;It suggested a possible lifecycle.&lt;/p&gt;

&lt;p&gt;At the time, however, I did not have same-account longitudinal evidence proving that transition.&lt;/p&gt;

&lt;p&gt;So the lifecycle remained a hypothesis.&lt;/p&gt;


&lt;h2&gt;
  
  
  Then the August 26 accounts changed
&lt;/h2&gt;

&lt;p&gt;Eventually, the same five accounts gave me the longitudinal evidence I was missing.&lt;/p&gt;

&lt;p&gt;All five underwent a major outbound contraction after previously occupying the roughly 7,400–7,800-following range, dropping into approximately 1,329–1,423 following.&lt;/p&gt;

&lt;p&gt;Their repository inventories remained essentially unchanged.&lt;/p&gt;

&lt;p&gt;That was important.&lt;/p&gt;

&lt;p&gt;The accounts had not simply vanished.&lt;/p&gt;

&lt;p&gt;Their social graphs had changed dramatically while their generated portfolios remained in place.&lt;/p&gt;

&lt;p&gt;One account gave an especially useful measurement.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;alberto4442&lt;/code&gt;, I was able to completely enumerate its public graph after pruning:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Following:   1,417
Followers:   1,556
Reciprocal:  1,413
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,413 / 1,417 = 99.7177%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or approximately:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;99.72%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;of the accounts it still followed also followed it back.&lt;/p&gt;

&lt;p&gt;That does not prove the pruning algorithm.&lt;/p&gt;

&lt;p&gt;I do not have a complete frozen copy of its pre-pruning following set, so I cannot identify exactly which relationships were removed.&lt;/p&gt;

&lt;p&gt;But it creates a strong testable hypothesis:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The contraction may preferentially preserve reciprocal relationships.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is much stronger than simply saying the account “looks like a follow-for-follow account.”&lt;/p&gt;

&lt;p&gt;It gives us something measurable.&lt;/p&gt;


&lt;h2&gt;
  
  
  Another generation appeared
&lt;/h2&gt;

&lt;p&gt;A later generation contained 14 additional owners, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sannejanhvb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;niransukdev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mhassanqjlh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ahmedbouugm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mhassanxglx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mbauerheabz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jsmithtikie&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sullivanolivia&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minjukimdev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jansensanne&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kwameagyeham&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;erikjohygkl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ananyasukhumvit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;anabauzttnd&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These accounts again exposed the exact &lt;code&gt;nancodero&lt;/code&gt; artifact.&lt;/p&gt;

&lt;p&gt;Their repositories used the same merge grammar.&lt;/p&gt;

&lt;p&gt;Their generated projects again followed recognizable skeletons.&lt;/p&gt;

&lt;p&gt;And repository operations were interleaved between owners rather than completing one account at a time.&lt;/p&gt;

&lt;p&gt;That matters.&lt;/p&gt;

&lt;p&gt;A simple process like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;generate account A
finish account A
generate account B
finish account B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;does not fit the observed chronology particularly well.&lt;/p&gt;

&lt;p&gt;The public history instead looked more like a scheduler or parallelized generation process multiplexing work across several owner namespaces.&lt;/p&gt;

&lt;p&gt;Again, that is a workflow inference.&lt;/p&gt;

&lt;p&gt;It is not operator attribution.&lt;/p&gt;


&lt;h2&gt;
  
  
  August 28 gave us a particularly useful generation
&lt;/h2&gt;

&lt;p&gt;Five more accounts appeared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;irenascent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vinamega&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RobbyDwk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nahladzulula&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cahcacah&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They exposed 60–61 repositories each.&lt;/p&gt;

&lt;p&gt;Their repository histories again contained:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merged PR #1
Automatically merged pull request #1
Co-authored-by: nancodero &amp;lt;nancodero@proton.me&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The generation also showed interleaved repository naming rounds involving projects such as:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Yarn*
Zen*
Zephyr*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;distributed across multiple owners.&lt;/p&gt;

&lt;p&gt;Several representative immutable commit objects remain publicly accessible:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;irenascent/ZephyrYarn
9404ead160e4f2434656d9f08e237780941be9f8

vinamega/ZephyrState
09d7f0d586e0afb66f0bf089a841a18361b5ad1f

RobbyDwk/ZephyrRift
6a01a7c5bff62c03e395f757ebf8ba1de4275f35

nahladzulula/ZephyrQuill
c66dfd255a812f1cf4d8c5a3378aa1f6a6c7667b

cahcacah/ZephyrIris
492860a52c17bb7547993ba89a1e714877c741dd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These are useful because the evidence does not depend entirely on mutable profile pages.&lt;/p&gt;

&lt;p&gt;The commit objects preserve the shared generation artifact.&lt;/p&gt;


&lt;h2&gt;
  
  
  Their social graphs then accelerated
&lt;/h2&gt;

&lt;p&gt;Initially, these five accounts had very few followers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Account&lt;/th&gt;
&lt;th&gt;Followers&lt;/th&gt;
&lt;th&gt;Following&lt;/th&gt;
&lt;th&gt;Repos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;irenascent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;843&lt;/td&gt;
&lt;td&gt;61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vinamega&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;799&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RobbyDwk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;799&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nahladzulula&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;637&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cahcacah&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;843&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Their repositories were already populated.&lt;/p&gt;

&lt;p&gt;Then their outbound-following counts expanded toward approximately 7,700.&lt;/p&gt;

&lt;p&gt;Follower counts climbed by hundreds.&lt;/p&gt;

&lt;p&gt;The repositories stayed fixed.&lt;/p&gt;

&lt;p&gt;That sequence is important:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repository generation
        ↓
portfolio reaches target state
        ↓
large outbound-follow expansion
        ↓
follower acquisition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The repository-building phase appears to precede the major social-growth phase.&lt;/p&gt;


&lt;h2&gt;
  
  
  Then all five followed me
&lt;/h2&gt;

&lt;p&gt;Immediately before this event, my public follower set contained 110 accounts.&lt;/p&gt;

&lt;p&gt;At the next collection it contained 115.&lt;/p&gt;

&lt;p&gt;The five additions were exactly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;irenascent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vinamega&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RobbyDwk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nahladzulula&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cahcacah&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No interpretation of GitHub’s endpoint ordering was required.&lt;/p&gt;

&lt;p&gt;This was a set difference:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;previous follower set
vs.
new follower set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Five additions.&lt;/p&gt;

&lt;p&gt;Five technically linked accounts.&lt;/p&gt;

&lt;p&gt;The entire generation entered together.&lt;/p&gt;

&lt;p&gt;That provides a useful clue about my position in this system.&lt;/p&gt;

&lt;p&gt;The workflow was already underway before these accounts followed me.&lt;/p&gt;

&lt;p&gt;Their repositories existed.&lt;/p&gt;

&lt;p&gt;Their generation artifacts existed.&lt;/p&gt;

&lt;p&gt;Their social acquisition had already started.&lt;/p&gt;

&lt;p&gt;So the evidence does not currently suggest that I am the origin of this activity.&lt;/p&gt;

&lt;p&gt;A more conservative explanation is that my account exists somewhere inside a reusable target population.&lt;/p&gt;

&lt;p&gt;Why it is there remains unknown.&lt;/p&gt;


&lt;h2&gt;
  
  
  Six more accounts repeated the sequence
&lt;/h2&gt;

&lt;p&gt;Another generation followed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emilybarru&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lgomesappj&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minseochoj&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;harutosati&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whitakeroliver&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;amurrayeqc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Initially, they exposed only around 11–12 public repositories each.&lt;/p&gt;

&lt;p&gt;Then something unusually clean happened.&lt;/p&gt;

&lt;p&gt;Every account gained exactly 67 public repositories.&lt;/p&gt;

&lt;p&gt;The final inventories became:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;79
79
79
79
78
78
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Across those owners, I recovered 466 exact-trailer merge commits across 466 repositories.&lt;/p&gt;

&lt;p&gt;The repositories again used the same &lt;code&gt;nancodero&lt;/code&gt; artifact.&lt;/p&gt;

&lt;p&gt;Then the social phase began.&lt;/p&gt;

&lt;p&gt;The six accounts moved to roughly:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~613–627 followers
~7,600 following
78–79 repositories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;while their repository inventories remained stable.&lt;/p&gt;

&lt;p&gt;And then my follower set changed again.&lt;/p&gt;

&lt;p&gt;A complete public enumeration moved from:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;111 followers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;117 followers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The six additions were exactly those six accounts.&lt;/p&gt;

&lt;p&gt;Again:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repository generation
        ↓
social acquisition
        ↓
coordinated entry into my follower set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At this point, the repeated timing was becoming much harder to explain as independent organic behavior.&lt;/p&gt;


&lt;h2&gt;
  
  
  The newest generation made the workflow even clearer
&lt;/h2&gt;

&lt;p&gt;On September 4, another group surfaced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tmokoenassz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lschmidtday&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;carlosgarjd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;akhalifazar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;canilmazdev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;elghazikhalid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;amanioumaaa&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;denizkayadev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rahulkumfqs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;srisawatanan&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;htanakaazwp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minhokingkim&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;emilywrightdev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thirteen accounts.&lt;/p&gt;

&lt;p&gt;Twelve exposed 17 repositories.&lt;/p&gt;

&lt;p&gt;One exposed 16.&lt;/p&gt;

&lt;p&gt;Owner-scoped searches recovered:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;219 exact-trailer merge commits across 219 repositories.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The observed production window ran from approximately:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-09-04 13:57:27 UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;through:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-09-04 18:02:54 UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Every recovered merge used the familiar structure:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merged PR #1
Automatically merged pull request #1
Co-authored-by: nancodero &amp;lt;nancodero@proton.me&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The repositories were again produced across multiple owner namespaces during the same bounded period.&lt;/p&gt;


&lt;h2&gt;
  
  
  The identity leakage continued too
&lt;/h2&gt;

&lt;p&gt;Some of these accounts display one persona while their repository histories expose another hard-coded identity.&lt;/p&gt;

&lt;p&gt;For example, one profile displays:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Anna
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;while sampled repository history contains:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thabomokoena@lazato.fun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Other commits across the workflow have used addresses under:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lazato.space
lazato.fun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These mismatches are valuable technical artifacts because they suggest that profile presentation and repository-generation identity are not consistently bound together.&lt;/p&gt;

&lt;p&gt;They are not evidence that any displayed name, email identity, or domain identifies the real operator.&lt;/p&gt;

&lt;p&gt;That distinction remains critical.&lt;/p&gt;


&lt;h2&gt;
  
  
  Then the generations connected through the social graph
&lt;/h2&gt;

&lt;p&gt;The newest accounts provided one of the strongest cross-generation observations so far.&lt;/p&gt;

&lt;p&gt;I successfully collected follower sets for eight of the new owners.&lt;/p&gt;

&lt;p&gt;Every one contained all five members of the August 28 generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;irenascent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vinamega&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RobbyDwk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nahladzulula&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cahcacah&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seven reciprocal following sets were also recovered.&lt;/p&gt;

&lt;p&gt;Four new owners had the exact same six-account following set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;irenascent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vinamega&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RobbyDwk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nahladzulula&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cahcacah&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aibers&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is more informative than finding generic high-degree follow-back hubs in multiple graphs.&lt;/p&gt;

&lt;p&gt;The five August 28 accounts had already been independently connected to the repository-generation workflow through Git artifacts before this social-graph relationship was examined.&lt;/p&gt;

&lt;p&gt;Now an older technically linked generation appears directly inside the initial social graph of a newer technically linked generation.&lt;/p&gt;

&lt;p&gt;That creates a cross-generation bridge using two different evidence classes:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git history
+
social graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Neither depends on the other.&lt;/p&gt;


&lt;h2&gt;
  
  
  A lifecycle is emerging
&lt;/h2&gt;

&lt;p&gt;Across the generations, the observations increasingly fit the following sequence:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;account creation
        ↓
automated/interleaved repository generation
        ↓
repository inventory reaches a target state
        ↓
older workflow accounts seed newer accounts' social graph
        ↓
large outbound-follow expansion
        ↓
hundreds or thousands of followers accumulate
        ↓
GnomeMan4201 is followed during the acquisition phase
        ↓
large-scale following-list pruning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Not every generation is currently at the same stage.&lt;/p&gt;

&lt;p&gt;That is important.&lt;/p&gt;

&lt;p&gt;A newly generated account should not be expected to already have 7,000 following or 1,500 followers.&lt;/p&gt;

&lt;p&gt;Lifecycle-stage differences should not be confused with evidence against linkage.&lt;/p&gt;

&lt;p&gt;The strongest linkage comes from higher-order technical artifacts such as the exact commit trailer, merge grammar, repository-generation morphology, interleaved chronology, template leakage, and cross-generation graph structure.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I think the evidence supports
&lt;/h2&gt;

&lt;p&gt;At this point I assess the following with high confidence:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple account generations participate in a common or closely related automated repository-generation and reputation-acquisition workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I also assess with high confidence that:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mass following and reciprocal relationships materially contribute to the social growth observed in at least some of these accounts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;alberto4442&lt;/code&gt; measurement is particularly strong:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,413 reciprocal relationships
out of
1,417 accounts followed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;99.72%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;after the major pruning event.&lt;/p&gt;

&lt;p&gt;The evidence also increasingly supports a phased lifecycle rather than a static account template.&lt;/p&gt;

&lt;p&gt;What changes between generations can be as informative as what stays the same.&lt;/p&gt;


&lt;h2&gt;
  
  
  What the evidence does not support
&lt;/h2&gt;

&lt;p&gt;There are several conclusions I am deliberately not making.&lt;/p&gt;

&lt;p&gt;I cannot establish that one human controls every account.&lt;/p&gt;

&lt;p&gt;I cannot establish that &lt;code&gt;nancodero&lt;/code&gt; is the operator.&lt;/p&gt;

&lt;p&gt;I cannot establish that identities appearing under &lt;code&gt;lazato.space&lt;/code&gt; or &lt;code&gt;lazato.fun&lt;/code&gt; correspond to the operator.&lt;/p&gt;

&lt;p&gt;I cannot determine why four earlier usernames now return 404.&lt;/p&gt;

&lt;p&gt;I cannot establish the exact algorithm responsible for pruning.&lt;/p&gt;

&lt;p&gt;I cannot establish the exact timestamp at which every account followed me because GitHub does not publicly expose follow-event timestamps.&lt;/p&gt;

&lt;p&gt;And I cannot establish that my account is being individually targeted.&lt;/p&gt;

&lt;p&gt;The current evidence fits something less dramatic and more operationally plausible:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My GitHub account appears to be a recurring member of a target population consumed by successive account-growth generations.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why remains an open question.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why the longitudinal evidence matters
&lt;/h2&gt;

&lt;p&gt;A screenshot can show that five accounts look similar.&lt;/p&gt;

&lt;p&gt;That is weak evidence by itself.&lt;/p&gt;

&lt;p&gt;A repository can show that two accounts use similar code.&lt;/p&gt;

&lt;p&gt;Also weak by itself.&lt;/p&gt;

&lt;p&gt;A high-degree follow-back account appearing in multiple follower sets is weak because such accounts naturally create enormous overlap.&lt;/p&gt;

&lt;p&gt;The case becomes more interesting when independent evidence classes begin converging:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shared immutable Git artifacts
+
shared repository morphology
+
interleaved generation chronology
+
cross-account template leakage
+
synchronized repository counts
+
synchronized social acquisition
+
cross-generation graph seeding
+
coordinated entry into the same target follower set
+
same-account longitudinal pruning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The individual observations are not equally strong.&lt;/p&gt;

&lt;p&gt;Their intersection is what matters.&lt;/p&gt;


&lt;h2&gt;
  
  
  The next experiment
&lt;/h2&gt;

&lt;p&gt;The strongest next test is straightforward.&lt;/p&gt;

&lt;p&gt;Before another mature account undergoes pruning, freeze its complete public follower and following sets.&lt;/p&gt;

&lt;p&gt;Record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub numeric account ID&lt;/li&gt;
&lt;li&gt;login&lt;/li&gt;
&lt;li&gt;collection timestamp&lt;/li&gt;
&lt;li&gt;followers&lt;/li&gt;
&lt;li&gt;following&lt;/li&gt;
&lt;li&gt;complete follower IDs&lt;/li&gt;
&lt;li&gt;complete following IDs&lt;/li&gt;
&lt;li&gt;repository inventory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then wait for the contraction.&lt;/p&gt;

&lt;p&gt;Afterward, collect the same graph again.&lt;/p&gt;

&lt;p&gt;That would let me divide the original following set into:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;retained relationships
removed relationships
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and directly test whether reciprocal relationships are disproportionately retained.&lt;/p&gt;

&lt;p&gt;If they are, the current 99.72% observation moves from a strong post-event clue toward direct behavioral evidence of the pruning mechanism.&lt;/p&gt;

&lt;p&gt;If they are not, the hypothesis gets weakened.&lt;/p&gt;

&lt;p&gt;Either result is useful.&lt;/p&gt;


&lt;h2&gt;
  
  
  Evidence companion
&lt;/h2&gt;

&lt;p&gt;The sanitized technical record, claim ledger, immutable Git anchors, and verification material are available here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/GnomeMan4201" rel="noopener noreferrer"&gt;
        GnomeMan4201
      &lt;/a&gt; / &lt;a href="https://github.com/GnomeMan4201/github-account-orchestration-study" rel="noopener noreferrer"&gt;
        github-account-orchestration-study
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;GitHub Account Orchestration Study&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A sanitized reproducibility package for a bounded OSINT investigation into six GitHub accounts that exhibited coordinated repository creation, outbound targeting, exact Git-object reuse, and commit-identity morphology.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Final assessment&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The released measurements strongly support a &lt;strong&gt;shared technical orchestration / generation system&lt;/strong&gt; across the six-account cohort.&lt;/p&gt;

&lt;p&gt;They do &lt;strong&gt;not&lt;/strong&gt; establish:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one human operator;&lt;/li&gt;
&lt;li&gt;shared credentials;&lt;/li&gt;
&lt;li&gt;shared IP or network infrastructure;&lt;/li&gt;
&lt;li&gt;a specific service, vendor, or account farm;&lt;/li&gt;
&lt;li&gt;deliberate targeting of the observer;&lt;/li&gt;
&lt;li&gt;publication-triggered discovery;&lt;/li&gt;
&lt;li&gt;malicious intent beyond the behavior directly measured.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Four evidence layers&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th&gt;Layer&lt;/th&gt;

&lt;th&gt;Released result&lt;/th&gt;

&lt;th&gt;Primary limitation&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;td&gt;Repository sequencing&lt;/td&gt;

&lt;td&gt;297/302 consecutive repository-creation transitions matched one six-account cycle (98.34%)&lt;/td&gt;

&lt;td&gt;five deviations retained; timestamps do not identify an operator&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;Outbound targeting&lt;/td&gt;

&lt;td&gt;three large reconciled following sets had Jaccard 0.9895–0.9906; four-way intersection 20,067&lt;/td&gt;

&lt;td&gt;two accounts failed completeness/stability validation and remain excluded&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;Git-object provenance&lt;/td&gt;

&lt;td&gt;10 exact blob SHAs crossed owner namespaces; six occurred under all six owners&lt;/td&gt;

&lt;td&gt;no cross-owner tree&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;…&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/GnomeMan4201/github-account-orchestration-study" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The original six-account study remains frozen and closed.&lt;/p&gt;

&lt;p&gt;Later observations are maintained as a separate longitudinal extension rather than being retroactively folded into the original protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;This investigation started because several GitHub followers looked unusually similar.&lt;/p&gt;

&lt;p&gt;That observation alone would not have justified much.&lt;/p&gt;

&lt;p&gt;The useful part came from refusing to stop at appearance.&lt;/p&gt;

&lt;p&gt;Freeze the baseline.&lt;/p&gt;

&lt;p&gt;Record the account IDs.&lt;/p&gt;

&lt;p&gt;Preserve the repositories.&lt;/p&gt;

&lt;p&gt;Compare the graphs.&lt;/p&gt;

&lt;p&gt;Follow the immutable artifacts.&lt;/p&gt;

&lt;p&gt;Keep negative results.&lt;/p&gt;

&lt;p&gt;Treat disappearing accounts as unresolved rather than inventing explanations.&lt;/p&gt;

&lt;p&gt;Separate technical linkage from human attribution.&lt;/p&gt;

&lt;p&gt;And wait for the system to change.&lt;/p&gt;

&lt;p&gt;Once you have longitudinal evidence, what initially looked like a collection of strange profiles starts becoming something much more measurable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a repeatable workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the part I am interested in documenting.&lt;/p&gt;

</description>
      <category>github</category>
      <category>security</category>
      <category>osint</category>
      <category>opensource</category>
    </item>
    <item>
      <title>108 TESTS PASSED.</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Fri, 04 Sep 2026 18:57:21 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/108-tests-passed-verified-32g</link>
      <guid>https://dev.to/gnomeman4201/108-tests-passed-verified-32g</guid>
      <description>&lt;p&gt;A green test suite is evidence. It is not independent evidence.&lt;/p&gt;

&lt;p&gt;The current release of &lt;strong&gt;badBANANA Threat Observatory&lt;/strong&gt; passes all 108 automated tests in its own development and CI environments. That tells me the implementation satisfies the assertions I wrote against the conditions I expected.&lt;/p&gt;

&lt;p&gt;It does not tell me whether an independent developer can check out the same commit in a clean environment and obtain the same result.&lt;/p&gt;

&lt;p&gt;That distinction matters more than the number 108.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dangerous failure is a believable one
&lt;/h2&gt;

&lt;p&gt;The Observatory presents source-backed threat-intelligence records, freshness information, and material-change events. In that kind of interface, an obvious crash is not necessarily the worst outcome.&lt;/p&gt;

&lt;p&gt;A more dangerous failure is one that looks healthy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An expired cached snapshot presented as current&lt;/li&gt;
&lt;li&gt;An invalid expiry value treated as usable&lt;/li&gt;
&lt;li&gt;A failed upstream source displayed as a successful zero-result response&lt;/li&gt;
&lt;li&gt;Demo or fallback data appearing without explicit disclosure&lt;/li&gt;
&lt;li&gt;A disabled or offline state silently normalized into success&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those failures do not merely inconvenience the user. They change what the interface appears to know.&lt;/p&gt;

&lt;p&gt;For v1.2.2, the intended behavior is deliberately fail-closed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Required behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cached snapshot has expired&lt;/td&gt;
&lt;td&gt;Report it as stale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expiry value is invalid&lt;/td&gt;
&lt;td&gt;Fail closed to stale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source is offline, disabled, or failed&lt;/td&gt;
&lt;td&gt;Preserve that state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source data is missing or unavailable&lt;/td&gt;
&lt;td&gt;Do not present a successful zero-result state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingestion requests overlap&lt;/td&gt;
&lt;td&gt;Enforce the runtime concurrency limit deterministically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feed credentials are configured&lt;/td&gt;
&lt;td&gt;Keep them server-side and absent from client output&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The test suite exercises these boundaries. The remaining question is whether the release reproduces cleanly outside the environment in which it was built.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing tests and independent verification are different claims
&lt;/h2&gt;

&lt;p&gt;When the source, tests, build assumptions, and execution environment all come from the same maintainer, a successful run demonstrates &lt;strong&gt;internal consistency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is necessary, but it can still preserve shared assumptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An undeclared local dependency&lt;/li&gt;
&lt;li&gt;An environment variable that exists on the maintainer’s machine&lt;/li&gt;
&lt;li&gt;A lockfile or package-manager difference&lt;/li&gt;
&lt;li&gt;Platform-specific filesystem behavior&lt;/li&gt;
&lt;li&gt;A test that passes without exercising the production build as expected&lt;/li&gt;
&lt;li&gt;A documented command sequence that no longer matches the release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running the same pinned artifact in an unrelated environment tests a different claim: &lt;strong&gt;independent reproducibility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That does not make one external run a complete audit. It does establish that the release is not only self-consistent inside its original environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The validation target is pinned
&lt;/h2&gt;

&lt;p&gt;The request is scoped to one release and one commit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Release:&lt;/strong&gt; &lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory/releases/tag/V1.2.2" rel="noopener noreferrer"&gt;V1.2.2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit:&lt;/strong&gt; &lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory/commit/2b80949fa500515554880ddebf20a2126d42836f" rel="noopener noreferrer"&gt;&lt;code&gt;2b80949fa500515554880ddebf20a2126d42836f&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime:&lt;/strong&gt; Node.js 22.13.0 or newer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory" rel="noopener noreferrer"&gt;GnomeMan4201/badBANANA-threat-observatory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live deployment:&lt;/strong&gt; &lt;a href="https://badbanana-threat-observatory.badbanana6969.workers.dev" rel="noopener noreferrer"&gt;badBANANA Threat Observatory&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pinning the target prevents a later commit, changed dependency, or updated deployment from silently becoming part of the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing the release
&lt;/h2&gt;

&lt;p&gt;From a clean environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/GnomeMan4201/badBANANA-threat-observatory.git
&lt;span class="nb"&gt;cd &lt;/span&gt;badBANANA-threat-observatory
git checkout V1.2.2
git rev-parse HEAD
node &lt;span class="nt"&gt;--version&lt;/span&gt;
npm &lt;span class="nt"&gt;--version&lt;/span&gt;
npm ci
npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expected result is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git rev-parse HEAD&lt;/code&gt; returns &lt;code&gt;2b80949fa500515554880ddebf20a2126d42836f&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The production build completes successfully.&lt;/li&gt;
&lt;li&gt;All &lt;strong&gt;108 automated tests&lt;/strong&gt; pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful report should record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operating system&lt;/li&gt;
&lt;li&gt;Node and npm versions&lt;/li&gt;
&lt;li&gt;Exact commit SHA&lt;/li&gt;
&lt;li&gt;Commands executed&lt;/li&gt;
&lt;li&gt;Test totals and final result&lt;/li&gt;
&lt;li&gt;Any behavior that differed from the expected result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Secrets should never be included in the report.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reproducible failure is also a successful result
&lt;/h2&gt;

&lt;p&gt;The goal is not to collect an approving comment.&lt;/p&gt;

&lt;p&gt;If the release fails in a clean environment, that is useful evidence provided the failure can be reproduced and bounded. The validation request can then point to a separate defect with its own environment details, reproduction steps, expected behavior, and observed behavior.&lt;/p&gt;

&lt;p&gt;That is better than treating an inconvenient result as noise or expanding one issue until it becomes impossible to close.&lt;/p&gt;

&lt;p&gt;The verification request therefore has two legitimate completion paths:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At least one independent clean-build report reproduces the expected result.&lt;/li&gt;
&lt;li&gt;A reproducible defect is identified and transferred into a separate bounded issue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The open verification request
&lt;/h2&gt;

&lt;p&gt;I have opened &lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory/issues/26" rel="noopener noreferrer"&gt;Issue #26: Independent validation requested—v1.2.2 evidence-integrity path&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have a clean Node.js environment and a few minutes, run the pinned procedure and add the result there. Confirming the release is valuable. Finding a reproducible failure is equally valuable.&lt;/p&gt;

&lt;p&gt;The broader principle is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests can show that a system agrees with its own specification. Independent reproduction tests whether that agreement survives contact with another environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For evidence-oriented software, verification should become part of the evidence.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>testing</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>🍌 pushed the badBANANA Threat Observatory public 🍌</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sun, 23 Aug 2026 23:10:31 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/i-pushed-the-badbanana-threat-observatory-public-49e8</link>
      <guid>https://dev.to/gnomeman4201/i-pushed-the-badbanana-threat-observatory-public-49e8</guid>
      <description>&lt;p&gt;This was one of those projects I had wanted to make for a long time, even before I had a very clear reason for it.&lt;/p&gt;

&lt;p&gt;Over the years, if you spend enough time around security, you keep seeing threat maps. A lot of them are visually impressive. They pull you in immediately. Lines moving across a globe, attacks firing in real time, counters climbing, everything looking active.&lt;/p&gt;

&lt;p&gt;But once I started learning more about how threat data actually works, I kept coming back to the same problem: a lot of those interfaces are more presentation than evidence.&lt;/p&gt;

&lt;p&gt;That is not necessarily a criticism. Some are demos, some are educational, some are marketing surfaces, and some are useful at a high level. But visually convincing does not always mean analytically meaningful.&lt;/p&gt;

&lt;p&gt;I wanted to build something that still had that same sense of observation and movement, but where the underlying data had to earn what the interface was showing.&lt;/p&gt;

&lt;p&gt;That is where the badBANANA Threat Observatory came from.&lt;/p&gt;

&lt;p&gt;It watches CISA KEV, ThreatFox, URLhaus, and MalwareBazaar, but the part I cared most about was not the dashboard itself. It was the evidence handling.&lt;/p&gt;

&lt;p&gt;I did not want missing data to become zeroes. I did not want bounded feeds to look complete. I did not want invalid indicators to get silently reclassified, impossible dates to roll into different dates, or malformed hashes to get truncated into something that looked valid.&lt;/p&gt;

&lt;p&gt;So the last stretch of the project was mostly audit work.&lt;/p&gt;

&lt;p&gt;I went through the source repeatedly looking for places where the system could accidentally overstate what it knew. That led to stricter IOC and hash validation, safer exports, better release provenance, client/server credential isolation checks, production deployment gates, and a lot of work around making sure the public release actually matched the exact source that had been reviewed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6old5c370p8nres1fcj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6old5c370p8nres1fcj0.png" alt=" " width="800" height="1421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The current version keeps a clear separation between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what a source says now&lt;/li&gt;
&lt;li&gt;what changed between observations&lt;/li&gt;
&lt;li&gt;what the system actually retained&lt;/li&gt;
&lt;li&gt;what was rejected&lt;/li&gt;
&lt;li&gt;what is missing or unavailable&lt;/li&gt;
&lt;li&gt;what cannot be proven from the available data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That distinction matters more to me than making the interface look “complete.”&lt;/p&gt;

&lt;p&gt;A bounded API should look bounded.&lt;/p&gt;

&lt;p&gt;A failed source should look failed.&lt;/p&gt;

&lt;p&gt;Missing confidence should stay missing.&lt;/p&gt;

&lt;p&gt;An unsupported record should not silently become something else.&lt;/p&gt;

&lt;p&gt;The Observatory is not meant to replace an analyst, and it is not trying to pretend that every event on screen is part of some live global cyberwar.&lt;/p&gt;

&lt;p&gt;It is meant to make the state of the evidence easier to inspect without quietly filling in the gaps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksdxwuzcxs5wm93k5zem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksdxwuzcxs5wm93k5zem.png" alt=" " width="800" height="1421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The public release went through multiple audit and remediation passes, including strict ThreatFox type handling, MalwareBazaar hash validation, spreadsheet safe exports, deployment hardening, metadata cleanup, and independent release provenance verification.&lt;/p&gt;

&lt;p&gt;Everything is public now.&lt;/p&gt;

&lt;p&gt;Live:&lt;br&gt;
&lt;a href="https://badbanana-threat-observatory.badbanana6969.workers.dev" rel="noopener noreferrer"&gt;https://badbanana-threat-observatory.badbanana6969.workers.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source:&lt;br&gt;
&lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory" rel="noopener noreferrer"&gt;https://github.com/GnomeMan4201/badBANANA-threat-observatory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Release:&lt;br&gt;
&lt;a href="https://github.com/GnomeMan4201/badBANANA-threat-observatory/releases/tag/v1.2.0" rel="noopener noreferrer"&gt;https://github.com/GnomeMan4201/badBANANA-threat-observatory/releases/tag/v1.2.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If anyone actually uses it and finds a concrete problem, I would rather hear about that than get praise for it.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>opensource</category>
      <category>threatintelligence</category>
    </item>
    <item>
      <title>Back to Basics: What a Forensic Investigation Can Prove — and What It Can’t</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Mon, 10 Aug 2026 10:35:49 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/back-to-basics-what-a-forensic-investigation-can-prove-and-what-it-cant-1d1n</link>
      <guid>https://dev.to/gnomeman4201/back-to-basics-what-a-forensic-investigation-can-prove-and-what-it-cant-1d1n</guid>
      <description>&lt;p&gt;This post is going back to the basics in forensic investigations.&lt;/p&gt;

&lt;p&gt;Not because the basics are simple.&lt;/p&gt;

&lt;p&gt;Usually it’s the opposite.&lt;/p&gt;

&lt;p&gt;Once an investigation starts producing interesting results, the boring rules become surprisingly easy to bend.&lt;/p&gt;

&lt;p&gt;You find the same pattern twice.&lt;/p&gt;

&lt;p&gt;Then some metadata lines up.&lt;/p&gt;

&lt;p&gt;Then the timing looks weird.&lt;/p&gt;

&lt;p&gt;Then another account appears.&lt;/p&gt;

&lt;p&gt;Then another repository.&lt;/p&gt;

&lt;p&gt;Pretty soon you have enough correlated evidence that your brain really wants there to be one clean explanation for all of it.&lt;/p&gt;

&lt;p&gt;That is usually the point where the most important question becomes:&lt;/p&gt;

&lt;p&gt;What does the evidence actually prove?&lt;/p&gt;

&lt;p&gt;I recently finished a GitHub investigation into what appeared to be a larger persona-fabrication or automated repository-production ecosystem.&lt;/p&gt;

&lt;p&gt;The case ended up producing some pretty strong evidence: repeated repository structures, shared content templates, recurring metadata, mechanically staged activity, cross-account relationships, and indicators that the behavior extended well beyond one isolated account.&lt;/p&gt;

&lt;p&gt;But one of the strongest attribution hypotheses still failed its locked threshold.&lt;/p&gt;

&lt;p&gt;That wasn’t the investigation breaking.&lt;/p&gt;

&lt;p&gt;That was the methodology working.&lt;/p&gt;

&lt;p&gt;A quick source note before going further: unless I explicitly call something an illustrative example, the measurements and examples below come from the case record. I’m keeping later external research separate from the closed investigation rather than quietly mixing the two.&lt;/p&gt;

&lt;p&gt;Start with what you observed&lt;/p&gt;

&lt;p&gt;One of the easiest mistakes in an investigation is jumping straight from an observation to an explanation.&lt;/p&gt;

&lt;p&gt;Something looks automated, so we call it automation.&lt;/p&gt;

&lt;p&gt;Two accounts behave similarly, so we start treating them as one operator.&lt;/p&gt;

&lt;p&gt;The same identity appears in metadata, so we start talking about control.&lt;/p&gt;

&lt;p&gt;That skips several evidentiary steps.&lt;/p&gt;

&lt;p&gt;In this case, accounts including ACCOUNT_A and ACCOUNT_B showed behavior that justified continuing the investigation.&lt;/p&gt;

&lt;p&gt;But the first useful statement wasn’t:&lt;/p&gt;

&lt;p&gt;These accounts are controlled by the same person.&lt;/p&gt;

&lt;p&gt;It was closer to:&lt;/p&gt;

&lt;p&gt;These accounts show repeatable technical and behavioral relationships worth testing.&lt;/p&gt;

&lt;p&gt;That sounds less exciting.&lt;/p&gt;

&lt;p&gt;It is also much harder to accidentally overstate.&lt;/p&gt;

&lt;p&gt;One repo can already tell you a lot&lt;/p&gt;

&lt;p&gt;A useful example from the case was REPO_01.&lt;/p&gt;

&lt;p&gt;Its activity contained a mechanically staged commit sequence compressed into roughly twenty seconds.&lt;/p&gt;

&lt;p&gt;That kind of timing is interesting.&lt;/p&gt;

&lt;p&gt;It can suggest automation, templating, scripted repository construction, or some other highly structured process.&lt;/p&gt;

&lt;p&gt;But even something that obvious has limits.&lt;/p&gt;

&lt;p&gt;A twenty-second construction sequence can support:&lt;/p&gt;

&lt;p&gt;highly structured repository creation&lt;/p&gt;

&lt;p&gt;It might support:&lt;/p&gt;

&lt;p&gt;likely automation or scripted workflow&lt;/p&gt;

&lt;p&gt;when combined with other evidence.&lt;/p&gt;

&lt;p&gt;It does not, by itself, tell you:&lt;/p&gt;

&lt;p&gt;who operated the account&lt;/p&gt;

&lt;p&gt;That difference sounds trivial until you are twenty pivots deep into an investigation.&lt;/p&gt;

&lt;p&gt;Repetition becomes much stronger when it survives removal&lt;/p&gt;

&lt;p&gt;One of the content-analysis results eventually found:&lt;/p&gt;

&lt;p&gt;26 shared nontrivial templates&lt;/p&gt;

&lt;p&gt;That was interesting, but there was an obvious question:&lt;/p&gt;

&lt;p&gt;What if one really distinctive string was carrying the whole result?&lt;/p&gt;

&lt;p&gt;The strongest normalized template was:&lt;/p&gt;

&lt;p&gt;update readme with clean structured content&lt;/p&gt;

&lt;p&gt;So the sensitivity test removed it and reran the calculation.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;p&gt;26 shared templates&lt;br&gt;
↓&lt;br&gt;
remove strongest template&lt;br&gt;
↓&lt;br&gt;
25 remain&lt;/p&gt;

&lt;p&gt;That is a legitimately useful result.&lt;/p&gt;

&lt;p&gt;The relationship did not disappear when the strongest individual feature was removed.&lt;/p&gt;

&lt;p&gt;But there is another basic distinction hiding here.&lt;/p&gt;

&lt;p&gt;Robustness isn’t specificity&lt;/p&gt;

&lt;p&gt;These are different questions.&lt;/p&gt;

&lt;p&gt;ROBUSTNESS&lt;br&gt;
Does the result survive removal of one feature?&lt;br&gt;
versus:&lt;br&gt;
SPECIFICITY&lt;br&gt;
How rare is the remaining pattern outside the subjects being tested?&lt;/p&gt;

&lt;p&gt;The 26 → 25 result gives us evidence about robustness.&lt;/p&gt;

&lt;p&gt;It tells us the result is not just one memorable phrase appearing twice.&lt;/p&gt;

&lt;p&gt;It does not automatically tell us those remaining 25 templates uniquely identify one person or one pair of accounts.&lt;/p&gt;

&lt;p&gt;For example, imagine a repository generator always produces:&lt;/p&gt;

&lt;p&gt;Add package.json&lt;br&gt;
Add .gitignore&lt;br&gt;
Add tests&lt;br&gt;
Update README&lt;/p&gt;

&lt;p&gt;That example is illustrative, not case evidence.&lt;/p&gt;

&lt;p&gt;If fifty accounts are generated by the same tooling, those strings might be great indicators of the tooling and terrible indicators of individual identity.&lt;/p&gt;

&lt;p&gt;That’s a distinction I think matters far beyond this particular investigation:&lt;/p&gt;

&lt;p&gt;A strong campaign signature is not automatically a strong identity signature.&lt;/p&gt;

&lt;p&gt;Metadata is evidence. It isn’t magic.&lt;/p&gt;

&lt;p&gt;Another important part of the investigation involved Co-authored-by trailers.&lt;/p&gt;

&lt;p&gt;Git commit messages can contain metadata like:&lt;/p&gt;

&lt;p&gt;Co-authored-by: Name&lt;/p&gt;

&lt;p&gt;In this investigation, recurring trailer identities became useful pivots.&lt;/p&gt;

&lt;p&gt;Later expansion work around TRAILER_ID, for example, was explicitly built around searching for and preserving occurrences of:&lt;/p&gt;

&lt;p&gt;Co-authored-by: TRAILER_ID&lt;/p&gt;

&lt;p&gt;That is valuable evidence.&lt;/p&gt;

&lt;p&gt;But it is still commit-message metadata.&lt;/p&gt;

&lt;p&gt;Someone can write a trailer into a commit message.&lt;/p&gt;

&lt;p&gt;So this:&lt;/p&gt;

&lt;p&gt;same trailer&lt;br&gt;
+&lt;br&gt;
same repository behavior&lt;br&gt;
+&lt;br&gt;
same content patterns&lt;br&gt;
+&lt;br&gt;
same timing characteristics&lt;br&gt;
+&lt;br&gt;
other independent relationships&lt;/p&gt;

&lt;p&gt;can become strong linkage evidence.&lt;/p&gt;

&lt;p&gt;This:&lt;/p&gt;

&lt;h1&gt;
  
  
  same Co-authored-by trailer
&lt;/h1&gt;

&lt;p&gt;same human&lt;/p&gt;

&lt;p&gt;does not follow.&lt;/p&gt;

&lt;p&gt;Again, that looks almost too obvious when written out.&lt;/p&gt;

&lt;p&gt;It gets much harder to remember once six or seven independent-looking signals are all pointing in roughly the same direction.&lt;/p&gt;

&lt;p&gt;Scale can change what the evidence means&lt;/p&gt;

&lt;p&gt;Another part of this investigation expanded beyond one or two repositories.&lt;/p&gt;

&lt;p&gt;The TRAILER_ID expansion branch exposed a set of 22 mechanically named security-oriented repositories, with names in the register of things like:&lt;/p&gt;

&lt;p&gt;SentinelHub&lt;br&gt;
HexaShield&lt;br&gt;
ZeroTrust&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;The scale matters.&lt;/p&gt;

&lt;p&gt;If you find the same artifact in two repositories, you might initially think in terms of a pairwise connection.&lt;/p&gt;

&lt;p&gt;If you later find related operational characteristics distributed across a much larger repository set, your interpretation may need to change.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;account A &amp;lt;----&amp;gt; account B&lt;/p&gt;

&lt;p&gt;you may be looking at something closer to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ┌── account
             ├── account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;shared process ──┼── account&lt;br&gt;
or tooling       ├── account&lt;br&gt;
                 └── account&lt;/p&gt;

&lt;p&gt;That is a very different claim.&lt;/p&gt;

&lt;p&gt;And it is not a weaker finding.&lt;/p&gt;

&lt;p&gt;Sometimes the most interesting outcome of trying to prove a pairwise relationship is discovering that you were measuring a larger system.&lt;/p&gt;

&lt;p&gt;Let the threshold fail&lt;/p&gt;

&lt;p&gt;This might be my favorite part of the whole case.&lt;/p&gt;

&lt;p&gt;One of the frozen hypotheses, T-H3, required a qualifying owner bridge to meet an owner-span threshold of:&lt;/p&gt;

&lt;p&gt;required owner span = 10&lt;/p&gt;

&lt;p&gt;The actual qualifying result was:&lt;/p&gt;

&lt;p&gt;owner_span = 2&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;p&gt;2 &amp;lt; 10&lt;br&gt;
T-H3 = FAIL&lt;/p&gt;

&lt;p&gt;That is the answer.&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;p&gt;but 2 looks suspicious&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;p&gt;the rest of the evidence is strong enough&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;p&gt;maybe 10 was too strict anyway&lt;/p&gt;

&lt;p&gt;The threshold was frozen before interpreting the result.&lt;/p&gt;

&lt;p&gt;If the rule says ten and the evidence gives you two, the hypothesis fails.&lt;/p&gt;

&lt;p&gt;Then you can investigate why it failed.&lt;/p&gt;

&lt;p&gt;Maybe the hypothesis was wrong.&lt;/p&gt;

&lt;p&gt;Maybe the evidence is describing a different phenomenon.&lt;/p&gt;

&lt;p&gt;Maybe the bridge is genuinely pair-specific.&lt;/p&gt;

&lt;p&gt;Maybe a later version of the methodology should test a different population.&lt;/p&gt;

&lt;p&gt;Those are all legitimate questions.&lt;/p&gt;

&lt;p&gt;What you cannot do is move the finish line because the evidence got close to the conclusion you wanted.&lt;/p&gt;

&lt;p&gt;Negative results are evidence too&lt;/p&gt;

&lt;p&gt;Suppose an investigation has hypotheses that roughly test:&lt;/p&gt;

&lt;p&gt;T-H0: ordinary / unrelated activity&lt;br&gt;
T-H1: meaningful shared-tooling or content relationship&lt;br&gt;
T-H2: structured distribution infrastructure&lt;br&gt;
T-H3: stronger ownership/control condition&lt;/p&gt;

&lt;p&gt;The actual result does not have to be a neat stack of successes.&lt;/p&gt;

&lt;p&gt;In this case, the more accurate summary was closer to:&lt;/p&gt;

&lt;p&gt;T-H1:&lt;br&gt;
high confidence / well-supported&lt;br&gt;
T-H2:&lt;br&gt;
moderate confidence&lt;br&gt;
plausible, but not independently identified&lt;br&gt;
T-H3:&lt;br&gt;
FAIL&lt;/p&gt;

&lt;p&gt;That is a useful result.&lt;/p&gt;

&lt;p&gt;In fact, it is much better than collapsing everything into:&lt;/p&gt;

&lt;p&gt;the accounts are connected&lt;/p&gt;

&lt;p&gt;because “connected” can mean almost anything.&lt;/p&gt;

&lt;p&gt;Shared content?&lt;/p&gt;

&lt;p&gt;Shared tooling?&lt;/p&gt;

&lt;p&gt;Shared automation?&lt;/p&gt;

&lt;p&gt;Same campaign?&lt;/p&gt;

&lt;p&gt;Same distribution infrastructure?&lt;/p&gt;

&lt;p&gt;Same operator?&lt;/p&gt;

&lt;p&gt;Same real-world human?&lt;/p&gt;

&lt;p&gt;Those are different propositions and should have different evidence requirements.&lt;/p&gt;

&lt;p&gt;The point of having separate hypotheses is that they are allowed to land differently.&lt;/p&gt;

&lt;p&gt;A result like “plausible but not independently identified” is not something that needs to be massaged into “supported.”&lt;/p&gt;

&lt;p&gt;It is the result.&lt;/p&gt;

&lt;p&gt;If every hypothesis magically succeeds, I would be more suspicious of the methodology than impressed by the investigation.&lt;/p&gt;

&lt;p&gt;The investigation even caught its own mechanism-level error&lt;/p&gt;

&lt;p&gt;There was another smaller but important example.&lt;/p&gt;

&lt;p&gt;After the analysis, the explanatory record around T-H3 needed correction.&lt;/p&gt;

&lt;p&gt;The final verdict itself did not change.&lt;/p&gt;

&lt;p&gt;The underlying result was still:&lt;/p&gt;

&lt;p&gt;owner_span = 2&lt;br&gt;
required = 10&lt;br&gt;
T-H3 = FAIL&lt;/p&gt;

&lt;p&gt;But the recorded explanation of why the rule failed was incomplete.&lt;/p&gt;

&lt;p&gt;The direct-bridge logic had effectively been described or implemented too narrowly, around same-commit or same-repository relationships, while the frozen rule also allowed a shared owner namespace to satisfy that bridge condition.&lt;/p&gt;

&lt;p&gt;So the bridge mechanism needed correcting.&lt;/p&gt;

&lt;p&gt;The threshold result did not.&lt;/p&gt;

&lt;p&gt;That distinction became AMENDMENT-001.&lt;/p&gt;

&lt;p&gt;I like this example because it captures another basic forensic rule:&lt;/p&gt;

&lt;p&gt;Correct the mechanism without rewriting the outcome.&lt;/p&gt;

&lt;p&gt;The important sequence was roughly:&lt;/p&gt;

&lt;p&gt;original interpretation&lt;br&gt;
↓&lt;br&gt;
mechanism-level discrepancy identified&lt;br&gt;
↓&lt;br&gt;
frozen rule checked&lt;br&gt;
↓&lt;br&gt;
bridge interpretation corrected&lt;br&gt;
↓&lt;br&gt;
owner_span still = 2&lt;br&gt;
↓&lt;br&gt;
T-H3 still FAIL&lt;/p&gt;

&lt;p&gt;The amendment made the explanation more accurate without pretending the earlier artifact had never existed.&lt;/p&gt;

&lt;p&gt;That matters.&lt;/p&gt;

&lt;p&gt;If an explanatory or implementation-level field changes, don’t replace the old record and erase the history.&lt;/p&gt;

&lt;p&gt;Preserve the lineage.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;original artifact&lt;br&gt;
↓&lt;br&gt;
hash&lt;br&gt;
↓&lt;br&gt;
identified mechanism-level defect&lt;br&gt;
↓&lt;br&gt;
documented amendment&lt;br&gt;
↓&lt;br&gt;
new artifact&lt;br&gt;
↓&lt;br&gt;
new hash&lt;/p&gt;

&lt;p&gt;The old artifact tells you what existed.&lt;/p&gt;

&lt;p&gt;The amendment tells you why it changed.&lt;/p&gt;

&lt;p&gt;The new artifact tells you what replaced it.&lt;/p&gt;

&lt;p&gt;A changed hash isn’t automatically suspicious&lt;/p&gt;

&lt;p&gt;This came up directly in the case.&lt;/p&gt;

&lt;p&gt;An earlier summary.json had one SHA-256 value.&lt;/p&gt;

&lt;p&gt;A later version had another.&lt;/p&gt;

&lt;p&gt;At first glance:&lt;/p&gt;

&lt;p&gt;old_hash != new_hash&lt;/p&gt;

&lt;p&gt;looks like an integrity problem.&lt;/p&gt;

&lt;p&gt;It might be.&lt;/p&gt;

&lt;p&gt;But hashes answer a very narrow question:&lt;/p&gt;

&lt;p&gt;Are these byte streams identical?&lt;/p&gt;

&lt;p&gt;If the contents legitimately changed, the hashes should differ.&lt;/p&gt;

&lt;p&gt;So you need provenance alongside integrity.&lt;/p&gt;

&lt;p&gt;Something conceptually like:&lt;/p&gt;

&lt;p&gt;Reproducibility Record v1&lt;br&gt;
summary.json&lt;br&gt;
sha256 = ...&lt;br&gt;
status = superseded, retained&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;AMENDMENT-001&lt;br&gt;
old_summary_sha256 = ...&lt;br&gt;
new_summary_sha256 = ...&lt;br&gt;
reason:&lt;br&gt;
mechanism-level explanatory correction&lt;br&gt;
method_changed = false&lt;br&gt;
outcome_changed = false&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;Reproducibility Record v2&lt;br&gt;
summary.json&lt;br&gt;
sha256 = ...&lt;/p&gt;

&lt;p&gt;Now the mismatch itself isn’t mysterious.&lt;/p&gt;

&lt;p&gt;You can explain exactly where it came from.&lt;/p&gt;

&lt;p&gt;A pretty useful way of remembering this is:&lt;/p&gt;

&lt;p&gt;A hash tells you whether the bytes changed. Provenance tells you why.&lt;/p&gt;

&lt;p&gt;Freeze the corpus too&lt;/p&gt;

&lt;p&gt;Another thing GitHub investigations make painfully obvious is that your evidence source is alive.&lt;/p&gt;

&lt;p&gt;Accounts keep working.&lt;/p&gt;

&lt;p&gt;Repositories change.&lt;/p&gt;

&lt;p&gt;New repositories appear.&lt;/p&gt;

&lt;p&gt;Search indexes update.&lt;/p&gt;

&lt;p&gt;Pull requests change.&lt;/p&gt;

&lt;p&gt;New matching artifacts can show up after you’ve already finished analyzing the original dataset.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;p&gt;CASE COMPLETE&lt;/p&gt;

&lt;p&gt;is not enough.&lt;/p&gt;

&lt;p&gt;What you really want is something closer to:&lt;/p&gt;

&lt;p&gt;case_status: complete&lt;br&gt;
evidence_cutoff:&lt;br&gt;
corpus_snapshot:&lt;br&gt;
protocol_version:&lt;br&gt;
analysis_version:&lt;br&gt;
result_as_of_cutoff:&lt;/p&gt;

&lt;p&gt;Then if you discover something tomorrow, you haven’t magically changed yesterday’s result.&lt;/p&gt;

&lt;p&gt;You have new evidence.&lt;/p&gt;

&lt;p&gt;That becomes an addendum or a new investigative phase.&lt;/p&gt;

&lt;p&gt;This distinction turned out to matter in this case because later GitHub research exposed additional accounts and workflow patterns beyond the frozen investigation.&lt;/p&gt;

&lt;p&gt;Those later observations may be valuable.&lt;/p&gt;

&lt;p&gt;But they should not quietly become retroactive evidence inside the original case.&lt;/p&gt;

&lt;p&gt;That is exactly how provenance gets muddy.&lt;/p&gt;

&lt;p&gt;Observation is not attribution&lt;/p&gt;

&lt;p&gt;The simplest mental model I’ve taken away from all of this is:&lt;/p&gt;

&lt;p&gt;OBSERVATION&lt;br&gt;
↓&lt;br&gt;
CORRELATION&lt;br&gt;
↓&lt;br&gt;
LINKAGE&lt;br&gt;
↓&lt;br&gt;
OPERATIONAL INFERENCE&lt;br&gt;
↓&lt;br&gt;
ATTRIBUTION&lt;/p&gt;

&lt;p&gt;Every arrow needs evidence.&lt;/p&gt;

&lt;p&gt;You might start with:&lt;/p&gt;

&lt;p&gt;OBSERVATION&lt;br&gt;
Multiple repositories contain recurring artifacts.&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;CORRELATION&lt;br&gt;
Those artifacts repeatedly occur alongside similar&lt;br&gt;
repository structure and timing.&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;LINKAGE&lt;br&gt;
Additional metadata or cross-repository relationships&lt;br&gt;
connect parts of the activity.&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;OPERATIONAL INFERENCE&lt;br&gt;
The behavior is consistent with shared tooling,&lt;br&gt;
automation, or coordinated repository production.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;p&gt;ATTRIBUTION&lt;br&gt;
These accounts belong to the same real-world person.&lt;/p&gt;

&lt;p&gt;is another evidentiary jump.&lt;/p&gt;

&lt;p&gt;You don’t get that arrow for free.&lt;/p&gt;

&lt;p&gt;What I would actually claim&lt;/p&gt;

&lt;p&gt;The evidence gave me enough confidence to say that the investigated GitHub activity contained repeated, highly structured operational signatures consistent with shared tooling, automation, templated repository production, or a broader coordinated workflow.&lt;/p&gt;

&lt;p&gt;The shared-tooling relationship was well supported.&lt;/p&gt;

&lt;p&gt;A more structured distribution-infrastructure explanation remained plausible, but I could not independently identify it strongly enough to treat it as established.&lt;/p&gt;

&lt;p&gt;The investigation also produced meaningful relationships between specific owner namespaces and recurring metadata identities.&lt;/p&gt;

&lt;p&gt;What I would not turn that into without stronger evidence is:&lt;/p&gt;

&lt;p&gt;account A == account B == one human operator&lt;/p&gt;

&lt;p&gt;The investigation’s strongest ownership/control hypothesis did not satisfy its frozen threshold.&lt;/p&gt;

&lt;p&gt;That boundary belongs in the result.&lt;/p&gt;

&lt;p&gt;The boring forensic rules matter&lt;/p&gt;

&lt;p&gt;After spending a lot of time on this case, the things I keep coming back to aren’t particularly exotic.&lt;/p&gt;

&lt;p&gt;Preserve the original evidence.&lt;/p&gt;

&lt;p&gt;Hash it.&lt;/p&gt;

&lt;p&gt;Preserve changed versions too.&lt;/p&gt;

&lt;p&gt;Document why they changed.&lt;/p&gt;

&lt;p&gt;Freeze the methodology before interpreting the final result.&lt;/p&gt;

&lt;p&gt;Do not move thresholds afterward.&lt;/p&gt;

&lt;p&gt;Keep commit metadata separate from authenticated identity evidence.&lt;/p&gt;

&lt;p&gt;Separate robustness from specificity.&lt;/p&gt;

&lt;p&gt;Separate pair-level evidence from campaign-level evidence.&lt;/p&gt;

&lt;p&gt;Keep later research separate from the frozen case corpus.&lt;/p&gt;

&lt;p&gt;Clearly label hypothetical examples.&lt;/p&gt;

&lt;p&gt;Timestamp the evidence boundary.&lt;/p&gt;

&lt;p&gt;Preserve failed hypotheses.&lt;/p&gt;

&lt;p&gt;Preserve partially supported hypotheses too.&lt;/p&gt;

&lt;p&gt;And don’t be afraid of an answer that is narrower than the one you expected.&lt;/p&gt;

&lt;p&gt;Because probably the most important rule is still:&lt;/p&gt;

&lt;p&gt;State the strongest conclusion the evidence can survive — not the strongest conclusion you can make the evidence resemble.&lt;/p&gt;

&lt;p&gt;That’s about as basic as forensic discipline gets.&lt;/p&gt;

&lt;p&gt;And the more interesting the investigation becomes, the more important those basics are.&lt;/p&gt;

</description>
      <category>security</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Git Diff for Human Reasoning</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Tue, 04 Aug 2026 22:23:27 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/-git-diff-for-human-reasoning-c17</link>
      <guid>https://dev.to/gnomeman4201/-git-diff-for-human-reasoning-c17</guid>
      <description>&lt;p&gt;Every investigation eventually reaches the same moment.&lt;/p&gt;

&lt;p&gt;Two competent people look at the same evidence and walk away believing different things.&lt;/p&gt;

&lt;p&gt;That isn't unusual. What's unusual is what happens next. We compare their conclusions. Not their reasoning. We argue over who is right. We almost never ask where they first began thinking differently.&lt;/p&gt;

&lt;p&gt;That struck me as backwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  We archive evidence. We rarely archive reasoning.
&lt;/h2&gt;

&lt;p&gt;Every investigation leaves behind artifacts. Logs. Disk images. Photographs. Witness statements. Source code. Those artifacts become part of the permanent record, indexed, hashed, preserved for years.&lt;/p&gt;

&lt;p&gt;Ironically, the reasoning that connected them usually disappears. The assumptions made along the way. The alternative explanations that were considered and rejected. The moment someone's confidence changed. Those things typically survive only in memory, in scattered notes, or in a conversation that was never written down at all.&lt;/p&gt;

&lt;p&gt;Weeks later, someone reviewing the investigation may have every piece of evidence the original investigator had — and almost none of the analytical path that made those pieces meaningful. When disagreement shows up, we reconstruct the reasoning after the fact instead of inspecting reasoning that was recorded as it happened.&lt;/p&gt;

&lt;p&gt;I began wondering whether that missing artifact — the reasoning itself was worth preserving. Not because it determines the truth. Because it explains how the truth was pursued.&lt;/p&gt;

&lt;p&gt;We preserve evidence remarkably well. We preserve reasoning remarkably poorly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every investigator leaves fingerprints
&lt;/h2&gt;

&lt;p&gt;Every investigator develops habits. Not bad habits, thinking habits.&lt;/p&gt;

&lt;p&gt;Some build a timeline first, before anything else. Some distrust timelines on instinct, because clocks drift and nobody double-checks them. Some constantly ask, "what evidence would change my mind?" Others ask, "what explains the most observations?" Some investigators are naturally skeptical of a source until it survives repeated scrutiny. Others are naturally generative — they build a hypothesis fast and spend the rest of the investigation trying to break it.&lt;/p&gt;

&lt;p&gt;Neither approach is wrong. They're different. And that's exactly why an investigation benefits from more than one independent person working it. If everyone followed the exact same process, they'd likely miss the exact same blind spots. Independent thinking isn't noise to eliminate. It's information to preserve.&lt;/p&gt;

&lt;p&gt;The problem was never that investigators think differently. The problem is that we usually throw away the record of &lt;em&gt;how&lt;/em&gt; they thought differently. By the time an investigation is written up, most of that path has disappeared into a polished narrative. The report tells you where they arrived. It rarely tells you the route they took.&lt;/p&gt;

&lt;p&gt;I started wondering if the route was actually the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if we could diff reasoning the way Git diffs code?
&lt;/h2&gt;

&lt;p&gt;Nobody reviews two versions of a file by reading each one top to bottom and holding the difference in their head. A diff tool does that reconstruction for you, it doesn't tell you which version is better, it just shows you exactly where and how they parted ways.&lt;/p&gt;

&lt;p&gt;When two investigators disagree, we still tend to do it the old way: put both reports side by side and ask a third person to reconstruct where the thinking diverged. That reconstruction is slow, it's subjective, and it's usually incomplete, because neither analyst ever recorded their reasoning in a form that could actually be compared.&lt;/p&gt;

&lt;p&gt;This does not mean nobody has tried to structure or preserve reasoning before. Structured analytic techniques, argument-mapping systems, and analytic-provenance tools have been doing parts of this work for years. I could not find a practical workflow centered specifically on freezing two independently authored reasoning paths, asking a separate reviewer to align them, and preserving those alignment decisions as part of the resulting diff. That narrower combination is what Reasoning Diff Lab is testing. A full treatment of the prior art, SEAS, CISpaces, W3C PROV, argument mapping, and the analytic-provenance literature is in the research assessment linked at the end.&lt;/p&gt;

&lt;p&gt;So I built enough of an answer to find out whether the question was worth asking. I called it &lt;strong&gt;Reasoning Diff Lab&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Status: pilot-ready, empirically unvalidated. The current v2.0.0 release includes the analyst-entry workflow, frozen path snapshots, reviewer alignment, deterministic comparison reports, and three synthetic cases. It passes 58 tests with 0 failures, and a full build produces 22 divergence events across those cases. That proves the instrument runs as designed. It does not prove that investigators will find it useful that is exactly what the pilot below is designed to determine.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually is
&lt;/h2&gt;

&lt;p&gt;It's a local-first research prototype that compares two independently produced reasoning paths against the same evidence set.&lt;/p&gt;

&lt;p&gt;I want to be just as clear about what it doesn't do, because this is the part that matters most. It does not determine truth, rank investigators, or declare one analyst better than the other. It does not infer a contradiction from wording a contradiction only exists in its output if a human reviewer explicitly confirms one. It does not replace human review; it tries to make that review faster to start, and harder to skip a step in.&lt;/p&gt;

&lt;p&gt;Each analyst breaks their reasoning into small typed pieces  an observation, an assumption, an inference, a claim, an explicit unknown and tags which evidence and which earlier piece each one depends on, with a confidence level attached. A reviewer who authored neither path matches the two sets: same position, related but distinct, or unrelated. Contradiction is separate it must be declared by the reviewer and is never guessed by the system. From there, everything is mechanical: the tool walks the matched and unmatched pieces and reports what it finds. If the report says two analysts diverged, you can trace that line back to the exact evidence, the exact dependency chain, and the exact reviewer decision whose call it was, and what they chose that produced it.&lt;/p&gt;

&lt;p&gt;What it surfaces in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shared evidence, different interpretation.&lt;/strong&gt; Both analysts cite the same authentication log. One reads it as stolen credentials. The other reads it as expired-token behavior. Same source, materially different explanation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evidence used by only one side.&lt;/strong&gt; One analyst built part of their case on the deployment timeline. The other never touched it — maybe for a good reason, maybe because they never saw it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence divergence.&lt;/strong&gt; Two analysts land on the same conclusion. One is 90% sure. The other is 55%. That gap is invisible if all you ever compare is the final sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undeclared support.&lt;/strong&gt; A claim exists with no evidence and no stated reasoning behind it. The tool doesn't call this wrong, it has no way to know if the analyst had a real reason they just didn't write down. It only reports, accurately, that nothing was declared.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  It isn't trying to merge two minds into one
&lt;/h2&gt;

&lt;p&gt;So the comparison engine isn't trying to reconcile two investigators into a single answer. It's trying to make the relationship between their reasoning inspectable. It just asks smaller, more answerable questions: which evidence did only one analyst use? Where did confidence start to pull apart? Did two people reach the same conclusion by entirely different paths?&lt;/p&gt;

&lt;p&gt;Those aren't answers. They're questions worth asking before a conclusion gets accepted as final. The goal isn't a verdict it's a shared language for disagreement, so it stops getting quietly absorbed into "well, we wrote two different reports."&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this falls short, on purpose and by accident
&lt;/h2&gt;

&lt;p&gt;Some of this is a real limitation I haven't solved; some of it is a boundary I drew on purpose and intend to keep. Match suggestions are lexical keyword overlap, nothing smarter a human reviewer has to confirm or reject every one. Structured entry is a genuine cost: breaking your own reasoning into typed pieces takes more effort than writing a paragraph, and I don't yet know if what it buys is worth what it costs. The five-part taxonomy might not fit how every investigator actually thinks.&lt;/p&gt;

&lt;p&gt;The first draft of this, in my head, was much bigger — a graph canvas, real-time collaboration, permission tiers, an API, a database, export pipelines, dashboards. None of that answers the only question that matters right now: does comparing reasoning paths reveal useful differences a normal review misses? So I cut it down to exactly what's needed to test that, and nothing else.&lt;/p&gt;

&lt;p&gt;A more detailed treatment covering prior art (SEAS, CISpaces, W3C PROV, argument mapping, structured analytic techniques), specific failure modes, the full data model, and the pilot protocol with predefined continuation and failure thresholds is in the repository under &lt;code&gt;docs/research-assessment-v0.1.md&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test
&lt;/h2&gt;

&lt;p&gt;The next step is small on purpose: two analysts, one reviewer, three cases, one straightforward, one genuinely ambiguous with no single correct answer, one noisy and incomplete on purpose. Each case also gets reviewed the ordinary way, prose only, no structure, as the baseline this has to beat.&lt;/p&gt;

&lt;p&gt;What gets measured: how long structured entry takes, how long review takes with the tool versus without it, how many reported differences a reviewer judges genuinely useful and non-obvious rather than just accurate, how many are misleading or simply wrong, what important differences the reviewer finds that the tool never surfaced at all, and whether anyone involved would choose to use it again.&lt;/p&gt;

&lt;p&gt;None of those numbers exist yet. That's the entire point of running the test instead of writing more code.&lt;/p&gt;

&lt;h2&gt;
  
  
  This isn't about replacing investigators
&lt;/h2&gt;

&lt;p&gt;The project is not intended to automate judgment or evaluate investigators. The most valuable part of an investigation is still the investigator: curiosity, experience, skepticism, pattern recognition, and the willingness to change direction when new evidence appears. A comparison engine cannot supply those things. If Reasoning Diff Lab succeeds, it will be because it made that judgment easier to inspect, discuss, and learn from not because it replaced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maybe this is a terrible idea
&lt;/h2&gt;

&lt;p&gt;Seriously. It might be. The reports may surface differences nobody actually cares about. The pilot may tell me I've spent months building an elegant answer to a question nobody was asking.&lt;/p&gt;

&lt;p&gt;That's a real possibility.&lt;/p&gt;

&lt;p&gt;But there's another one. Maybe disagreement isn't something to eliminate maybe it's something to inspect. Maybe the interesting artifact was never the final conclusion. Maybe it's the moment two careful people quietly stopped thinking the same way.&lt;/p&gt;

&lt;p&gt;I don't know. That's why this exists. Not to prove the idea. To test it.&lt;/p&gt;

&lt;p&gt;If it fails, I want to know why. If it succeeds, I want to know why. Either result is worth more than convincing myself it works from the inside.&lt;/p&gt;




&lt;p&gt;I'm looking for pilot participants. If you investigate things for a living—incident response, intelligence, digital forensics, journalism, medicine, security research, or even debugging—and you're willing to run the included synthetic cases through this and tell me exactly where the workflow broke, wasted your time, or showed you something you would otherwise have missed, I want to hear from you.&lt;/p&gt;

&lt;p&gt;The initial pilot requires two independent analysts and one reviewer, takes approximately 90 minutes, runs locally, and does not require participants to submit real investigative evidence.&lt;/p&gt;

&lt;p&gt;Everything needed to inspect or run the pilot is available here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/GnomeMan4201/reasoning-diff-lab" rel="noopener noreferrer"&gt;Project repository and v2.0.0 release&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/GnomeMan4201/reasoning-diff-lab/blob/main/docs/research-assessment-v0.1.md" rel="noopener noreferrer"&gt;Research assessment&lt;/a&gt;&lt;/strong&gt; — prior art, failure modes, data model, and predefined continuation and failure thresholds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/GnomeMan4201/reasoning-diff-lab/blob/main/docs/EXPERIMENT_PROTOCOL.md" rel="noopener noreferrer"&gt;Pilot protocol&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/GnomeMan4201/reasoning-diff-lab/blob/main/docs/FACILITATOR_PACKET.md" rel="noopener noreferrer"&gt;Facilitator packet&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comment below, open a GitHub issue, or reach out through my DEV profile. The next meaningful edit to this project should happen after real participants break, validate, or complicate the hypothesis—not before.&lt;/p&gt;

&lt;p&gt;Evidence tells us what happened. Reasoning tells us why we believed it. We preserve the first remarkably well. I'm interested in whether we should start preserving the second.&lt;/p&gt;

</description>
      <category>security</category>
      <category>opensource</category>
      <category>discuss</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>r4b1t_h0le</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Thu, 18 Jun 2026 01:08:28 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/r4b1th0l3-5aa3</link>
      <guid>https://dev.to/gnomeman4201/r4b1th0l3-5aa3</guid>
      <description>&lt;h2&gt;
  
  
  Explore r4b1t_h0le
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://r4b1t.badbananaresearch.com" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Open the r4b1t_h0le discovery instrument&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/GnomeMan4201/r4b1t" rel="noopener noreferrer"&gt;View the source&lt;/a&gt; · &lt;a href="https://gnomeman4201.github.io/r4b1t/" rel="noopener noreferrer"&gt;Launch the original application&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a curated random link generator for security and OSINT researchers. &lt;strong&gt;50,109 structurally valid URLs across 12,396 unique hosts.&lt;/strong&gt; Roll one. See what happens.&lt;/p&gt;

&lt;p&gt;basically StumbleUpon for your niche. That's the point. StumbleUpon worked. Nobody built a replacement for it when it died, especially not for security research. So I wanted to make something that breaks you free of that feeling of being contained within the algorithm/echo chambers we all congregate nowadays.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a real session looks like
&lt;/h2&gt;

&lt;p&gt;I opened the tool this morning. Here's what I did, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;cvedb.shodan.io&lt;/strong&gt; — Shodan's CVE database. Structured vulnerability data, searchable, free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hnd.techlearningcollective.com&lt;/strong&gt; — Hackers Next Door, an infosec conference I'd never heard of.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;easyperf.net&lt;/strong&gt; — Performance engineering blog. Low-level, serious, no fluff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;engineeringblog.yelp.com/2014/11/scaling-elasticsearch&lt;/strong&gt; — 2014 Yelp post on Elasticsearch at scale. Still accurate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;domains-index.com&lt;/strong&gt; — Domain registration intelligence. OSINT pivoting tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;metapicz.com&lt;/strong&gt; — EXIF metadata viewer. Forgot this existed. Bookmarked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;discover.maxar.com&lt;/strong&gt; — Satellite imagery browser. Geospatial OSINT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;github.com/jamesm0rr1s/BurpSuite-Add-and-Track-Custom-Issues&lt;/strong&gt; — BurpSuite extension I didn't know existed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;insanecoding.blogspot.co.uk/2014/05/a-good-idea-with-bad-usage-devurandom&lt;/strong&gt; — Post on /dev/urandom misuse from 2014. Referenced everywhere, never read it until now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;en.wikipedia.org/wiki/Software_development&lt;/strong&gt; — Wikipedia. In a pool of 50,000+ URLs this came up. I hit SPROUT on it anyway.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ten rolls. Two tools I'm adding to my workflow. One conference I'm looking up. Three things I'd completely forgotten existed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx77rg9gnt7a21w1t2pzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx77rg9gnt7a21w1t2pzz.png" alt="r4b1t_h0le — OG card preview with trail bar" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is just a few examples… I have found some hidden gems while developing this on my spare time.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works — entirely in your browser
&lt;/h2&gt;

&lt;p&gt;(My main goal was to just keep it simple. Bare bones.)&lt;/p&gt;

&lt;p&gt;The entire pool loads into a JavaScript array in memory on page open. One 2MB fetch of a plain text file. Everything else runs client-side. No backend decides what you see. No server query on each roll. No tracking.&lt;/p&gt;

&lt;p&gt;Rolling a URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
    &lt;span class="nx"&gt;attempts&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^www&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;domainCount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;lastUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Domain diversity is enforced in the roll….you won't see the same domain more than twice in 25 attempts. &lt;strong&gt;12,396 unique hosts in the current frozen baseline.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SPROUT — semantic navigation without AI
&lt;/h2&gt;

&lt;p&gt;(Visually needed something instead of a normal list of useful URLs.) &lt;/p&gt;

&lt;p&gt;Hit SPROUT on any URL and get four directional suggestions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEEPER&lt;/strong&gt; — further into this niche&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIDEWAYS&lt;/strong&gt; — adjacent territory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OPPOSITE&lt;/strong&gt; — contrasting view&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WEIRD&lt;/strong&gt; — unexpected tangent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I originally used the Anthropic API for this. It worked. Then I ripped it out. Paying for tokens was a big pain I had to find a solution for. &lt;/p&gt;

&lt;p&gt;What actually happens now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the OG title + description already fetched for the preview card (zero extra cost)&lt;/li&gt;
&lt;li&gt;Query Wikipedia's free API for the domain — get the intro extract and article categories&lt;/li&gt;
&lt;li&gt;Extract top keywords by frequency, filtered against a stopword list&lt;/li&gt;
&lt;li&gt;Score the pool by keyword overlap using Jaccard similarity
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;xe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kw&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;kw&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Runs against up to 3,000 randomly sampled URLs. In milliseconds. In your browser. No API key. No cost. No rate limit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where it fails:&lt;/strong&gt; OG metadata is often garbage or generic descriptions, SEO spam, or missing entirely. When that happens SPROUT falls back to URL-only token matching, which is coarser. I accepted this tradeoff over adding an AI dependency. The WEIRD direction is intentionally low-signal… it's supposed to surprise you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw5vxc37ifcdi7eaigr6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw5vxc37ifcdi7eaigr6c.png" alt="BRANCH mode with SPROUT directions" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(I’m aware Long term maintenance of giant pools is always gonna be a nightmare later on. This is the route I chose for the time being.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The pool — and the link rot problem
&lt;/h2&gt;

&lt;p&gt;Starting corpus: ~120,000 URLs from Start.me OSINT pages and GitHub awesome-lists across 21 categories. Every URL swept with HEAD requests, 10 second timeout, 50 concurrent workers, results checkpointed to SQLite.&lt;/p&gt;

&lt;p&gt;Current frozen evidence baseline: &lt;strong&gt;50,109 structurally valid URLs across 12,396 unique hosts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Yes, it's my curated bookmarks folder. That's also the point — random across the whole internet is noise. The curation is what makes the randomness useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link rot:&lt;/strong&gt; A GitHub Actions workflow runs &lt;code&gt;pool_sweep.py&lt;/code&gt; every Sunday, hits every URL, and auto-commits the pruned pool. Dead links get culled weekly. It's not perfect — a site can return 200 while serving a parking page — but it catches the obvious rot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do
&lt;/h2&gt;

&lt;p&gt;No login. No analytics. No recommendation engine. No ads. The Cloudflare Worker handles OG metadata fetching only — origin-locked, rate limited at 60 req/min per IP, RFC1918 blocked. The core loop — roll, visit, skip — works without it entirely.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://r4b1t.badbananaresearch.com" rel="noopener noreferrer"&gt;r4b1t.badbananaresearch.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Original application: &lt;a href="https://gnomeman4201.github.io/r4b1t/" rel="noopener noreferrer"&gt;gnomeman4201.github.io/r4b1t&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/GnomeMan4201/r4b1t" rel="noopener noreferrer"&gt;github.com/GnomeMan4201/r4b1t&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Submit a URL: &lt;a href="https://github.com/GnomeMan4201/r4b1t/issues/new?labels=url-submission" rel="noopener noreferrer"&gt;GitHub Issues&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;badBANANA Research Collective&lt;/em&gt;&lt;/p&gt;

</description>
      <category>osint</category>
      <category>security</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Two Doors Into the Same Room</title>
      <dc:creator>GnomeMan4201</dc:creator>
      <pubDate>Sat, 06 Jun 2026 01:07:50 +0000</pubDate>
      <link>https://dev.to/gnomeman4201/two-doors-into-the-same-room-5fd2</link>
      <guid>https://dev.to/gnomeman4201/two-doors-into-the-same-room-5fd2</guid>
      <description>&lt;h2&gt;
  
  
  The Destruction Side: Phrack Magazine
&lt;/h2&gt;

&lt;p&gt;Phrack is a self‑published hacker zine founded in 1985, distributed via dial‑up bulletin board systems (BBS) rather than mainstream media. Its name combines "phreak" (phone phreaking) and "hack," reflecting its content. Early Phrack issues were gritty compilations of phone‑phreaking techniques, war stories, and even how‑to bomb recipes knowledge freely shared among curious technologists. Crucially, Phrack emphasized that understanding systems is not malice: Issue 7 (Jan 1986) published Loyd Blankenship's "The Conscience of a Hacker," popularly known as the Hacker Manifesto. In it a teenage hacker protests that "My crime is that of curiosity", not malice. The essay asserts that hacking has a purpose beyond selfish gain to expand our horizons and keep the world free. This defense of pure curiosity over vandalism has echoed through hacker culture for decades.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Phrack milestones:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1986 (Issue 7):&lt;/strong&gt; Published "The Conscience of a Hacker" by The Mentor — the original Hacker Manifesto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1996 (Issue 49):&lt;/strong&gt; "Smashing The Stack for Fun and Profit" by Aleph One, the seminal buffer‑overflow tutorial, which taught a generation of security researchers how stack overflows work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1997 (Issue 51):&lt;/strong&gt; "The Art of Port Scanning" by Fyodor, introducing the Nmap tool its full source code was appended for readers to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal clash:&lt;/strong&gt; In 1989, Phrack published an internal BellSouth Enhanced-911 memo. Editor Craig "Knight Lightning" Neidorf was arrested (Operation Sundevil), but the Electronic Frontier Foundation intervened. The case collapsed when it was shown the same document cost $13.50 from BellSouth. This episode became a catalyst for EFF's founding and underscored that knowledge itself was treated as a criminal threat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Throughout, Phrack was run by volunteers with no corporate backing. It tracked hacking and phreaking culture through the 1990s and beyond, reflecting the scene's shifts from telephone systems to computer security. Today all 72 issues (1985–2025) remain freely available on phrack.org, demonstrating Phrack's continuity. As its current introduction proudly notes, "For 40 years, Phrack has published papers that have reflected and shaped hacker culture… Phrack is written by hackers, for hackers."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Creative Side: Newgrounds
&lt;/h2&gt;

&lt;p&gt;Newgrounds began as a teenage passion project, not a polished startup. In 1991, 13‑year‑old Tom Fulp created a Neo Geo console fanzine called New Ground, mailing it to ~100 Prodigy online service members. When the web arrived, he turned it into New Ground Remix (1995) and started uploading Flash animations and games people sent him. In the mid‑1990s he made crude, amateur Flash games Club a Seal, Assassin, which drew attention for being transgressive yet exuberant. These early projects showed the platform's ethos: everything goes, as long as it's tagged with an appropriate content rating.&lt;/p&gt;

&lt;p&gt;The watershed came on April 6, 2000, when Fulp and collaborator Ross Snyder launched the automated Newgrounds Portal. For the first time, anyone could upload a Flash animation or game directly to the site with no gatekeeper years before YouTube or social media existed. Newgrounds' own history calls this "changing the landscape of the Internet forever," because it provided "an instant publishing system for games and movies." It let rough, amateur creations find an audience. In 1999, Fulp's own Flash game &lt;em&gt;Pico's School&lt;/em&gt; was noted for its polish and credited with launching the Flash games boom.&lt;/p&gt;

&lt;p&gt;Newgrounds' content was wildly varied: crude and brilliant, juvenile and visionary, often all at once. Every piece of user content could be rated Everyone, Teen, Mature, or Adult, but nothing was outright censored if rated. This openness meant real risk-taking: games could flop or they could become phenomena. A striking example is the "Numa Numa" meme: in December 2004, teenager Gary Brolsma uploaded a silly lip-sync video of himself on Newgrounds. Before YouTube took off, his "Numa Numa Dance" racked up millions of views, teaching the internet about viral media. More recently, in April 2021 the Newgrounds debut of the indie rhythm game &lt;em&gt;Friday Night Funkin'&lt;/em&gt; made by a four-person team drew an unprecedented crowd. Tom Fulp reported "Friday Night Funkin' had 1.2 million plays, a new single‑day record for anything on the site" so much traffic it briefly crashed the site.&lt;/p&gt;

&lt;p&gt;Newgrounds remains independent and user‑funded. There are no venture capitalists or mass ad-tracking. Its founder proudly reminds users: "I created Newgrounds. It wasn't made by some giant company; just some dumb kid who now has help." The site solicits voluntary Supporter subscriptions ($25/year) to stay 100% ad-free and does not sell personal data. Its goal is to remain independent so creators get a space to share freely.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Same Room
&lt;/h2&gt;

&lt;p&gt;On the surface, Phrack and Newgrounds seem very different one is a technical hacker journal, the other a haven for Flash games and cartoons. Yet structurally they're remarkably alike. Both were built by individuals who refused to wait for permission and had no corporate umbrella. Each grew out of hobbyist networks when mainstream institutions didn't recognize the value of what they were doing. Both treated their subject matter with utter seriousness while the wider culture still dismissed it: Phrack saw phreaking as a deep craft, Newgrounds saw creative experimentation as worth showcasing. Both survived for decades on volunteer labor and fan loyalty, not venture funding or ad revenue.&lt;/p&gt;

&lt;p&gt;Each delivered a similar feeling to its discoverers: &lt;em&gt;we found a secret door into a room where the conversation was already happening.&lt;/em&gt; For Phrack readers, that meant seeing the knowledge architecture of telephony and computing laid bare learning that the system can be understood, and that understanding it is not a crime. For Newgrounds visitors, it meant discovering that you can make something and share it without approval. Early users remember refreshing the homepage obsessively for new cartoons or games. In both cases the message was radical: you don't need to ask a gatekeeper to exist online, and the unfinished or even "bad" work has value.&lt;/p&gt;

&lt;p&gt;Phrack's Manifesto argued that hacking is driven by curiosity and community, not malice. Newgrounds' structure embodied the idea that genuine creative expression doesn't require polishing for advertisers it's okay to be messy, experimental, or offensive as long as it's labeled. Both insisted that knowledge and creativity should be shared freely, without algorithms deciding who deserves an audience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why It Still Matters
&lt;/h2&gt;

&lt;p&gt;Unlike most early internet projects, both Phrack and Newgrounds are still alive. Phrack's entire run Issues 1–72, November 1985 through August 2025 is online in plaintext with no paywall. Newgrounds is still run by Tom Fulp from his office in suburban Pennsylvania, averaging tens of millions of views per month on community-made content, paid for by fan supporters rather than ads.&lt;/p&gt;

&lt;p&gt;Neither fits the current mold of the web. They aren't optimized for ad revenue, they don't run recommendation algorithms, and they don't sanitize content to appease sponsors. They live on through communal love. Their survival proves a point: the web can still be a room where curious people gather and speak freely.&lt;/p&gt;

&lt;p&gt;Both of these platforms shaped how I think. Newgrounds taught me that I can express myself through art and code... Phrack taught me that understanding a system really understanding it isn't the same as attacking it. They are pioneers for pushing through the friction no matter how messy, and that distinction has mattered to me in ways that go well beyond code.&lt;/p&gt;

</description>
      <category>webhistory</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>culture</category>
    </item>
  </channel>
</rss>
