惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threat Research - Cisco Blogs
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
H
Heimdal Security Blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
The Last Watchdog
The Last Watchdog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
D
DataBreaches.Net
I
Intezer
Webroot Blog
Webroot Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
罗磊的独立博客
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
Schneier on Security
Schneier on Security
宝玉的分享
宝玉的分享
博客园 - 叶小钗
PCI Perspectives
PCI Perspectives
D
Docker
Scott Helme
Scott Helme
NISL@THU
NISL@THU
J
Java Code Geeks
B
Blog RSS Feed
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Exploit Database - CXSecurity.com
AI
AI
美团技术团队
Cloudbric
Cloudbric
月光博客
月光博客
P
Proofpoint News Feed
T
Tailwind CSS Blog
Google DeepMind News
Google DeepMind News
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
The Cloudflare Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
From Repo Scanner to Audit Architecture: What Changed in STEM BIO-AI Through v1.7.8
Kwansub Yun · 2026-05-19 · via DEV Community

From repo scanner to audit architecture: the evolution of STEM BIO-AI through v1.7.8

Three technical changes that made the scanner less Python-shaped, the warning model more stable, and the reports more inspectable.

The last time I wrote about STEM BIO-AI, the focus was AIRI:

how a local repository scanner could expand its risk vocabulary without pretending to become a universal AI safety judge.

That was the right story for 1.7.0 and 1.7.1.

But the project changed meaningfully after that.

For readers who have not followed the earlier posts: Beyond Repo Scanning: How AIRI Expanded the Risk Vocabulary in STEM BIO-AI 1.7.x

By 1.7.8, the interesting question was no longer just:

Can this scanner attach a broader risk language to local findings?

It became:

Can this scanner make those findings more inspectable, less misleading, and more robust across real repository shapes?

That shift matters.

Because in audit tooling, correctness is only the first battle. The second battle is whether a reviewer can see why the tool landed where it did, and whether the output still makes sense when it leaves the terminal and becomes a report, a PDF packet, a Hugging Face demo, or a governance memo.

From 1.7.6 through 1.7.8, three changes mattered most.

They changed:

  1. what counts as evidence,
  2. how warning lanes are separated,
  3. and how the final artifact stays legible across surfaces.

This is the more technical story behind those releases.


Basic AIRI(the AI Risk Repository) Context: Expanding the Language of Risk

Before getting into the release details, it helps to define what AIRI means in this series.

AIRI refers here to the MIT AI Risk Repository: a public AI risk resource from the MIT AI Risk Initiative that organizes fragmented AI risk language across research, policy, and industry sources.

The repository includes an AI Risk Database, a Causal Taxonomy of AI Risks, and a Domain Taxonomy of AI Risks. According to the MIT AI Risk Repository site, the database collects 1,700+ risks from 74 existing AI risk frameworks and classifications, while the public domain taxonomy organizes risks into 7 domains and 24 subdomains.

That makes AIRI useful as a vocabulary source.

But vocabulary is not truth.

A local scanner should not say:

this repository caused this risk.

It should say something more careful:

this local finding belongs to a broader class of AI risk language.

That distinction is the design boundary.


1. Problem: The scanner was still too Python-shaped

Universal dependency detection and provenance evidence across Python and JavaScript stacks

One of the more useful failures in this line came from an uncomfortable result: a repository could obviously have dependency and lockfile evidence, and STEM BIO-AI could still miss it.

That is not a philosophical problem.
That is an implementation problem.

In practice, the project was still too biased toward Python-native signals.

That showed up most clearly in JavaScript or mixed-stack repositories:

  • package.json
  • package-lock.json
  • pnpm-lock.yaml
  • yarn.lock
  • npm-shrinkwrap.json

were not being treated as first-class provenance and replication evidence in the same way that requirements.txt or pyproject.toml were.

The result was a false negative pattern:

  • Stage 3 provenance (B1) could be undercounted
  • Stage 4 replication evidence could be undercounted
  • and the report could quietly imply "no dependency evidence" when the repository clearly had dependency structure

That kind of miss is more dangerous than it sounds.

Not because it makes the score a little wrong.

But because it damages trust in the scanner's worldview.

If developers see a tool miss an obvious pnpm-lock.yaml, they stop believing the harder claims too.


What changed in 1.7.6

The fix was straightforward but important:

  • JavaScript manifests and lockfiles were promoted into the same evidence families as the existing Python manifests where appropriate.

Concretely, that meant:

  • B1_data_provenance_controls started recognizing JS manifest/lock surfaces
  • S4_environment_lock_evidence started recognizing them
  • S4_exact_dependency_pins_or_hashes started recognizing them

This was not a scoring philosophy change.

It was a scope correction.

The rule engine learned that a dependency ecosystem is a dependency ecosystem even when it is not Python.

One boundary matters here.

B1_data_provenance_controls does not suddenly mean "dataset lineage was proven by a lockfile."

In this lane, B1 is using dependency manifests as repository provenance surfaces:

  • what environment the repository expects,
  • what dependency custody the repository exposes,
  • and whether the repo surfaces any adjacent data-source, IRB, or dataset-citation language around that environment.

That is weaker than dataset lineage evidence.

But it is also much stronger than pretending a mixed-stack repository has no provenance surface at all.


A small before/after that makes the point

The yorkeccak/bio case is a good example because the score movement was not philosophical. It was mechanical.

Before the JS manifest fix, the same repository could produce:

version: 1.7.5
final_score: 40
stage_3_code_bio: 6
B1_data_provenance_controls: 0 / 15
replication_score: 10
AIRI covered_count: 0 / 31

Enter fullscreen mode Exit fullscreen mode

After the manifest and lockfile correction, the same repository shape produced:

version: 1.7.8
final_score: 48
stage_3_code_bio: 25
B1_data_provenance_controls: 15 / 15
replication_score: 30
AIRI covered_count: 7 / 32

Enter fullscreen mode Exit fullscreen mode

The important part is not the score delta by itself.

One small boundary is worth making explicit here.

The AIRI change is doing two things at once:

  • the denominator moved from 31 to 32 because the governed AIRI detector-scope expanded by one mapping row across this release line,
  • and the numerator moved from 0 to 7 because the current release can now carry more bounded AIRI links around the findings it actually surfaced.

That explains the AIRI coverage delta.

The scoring delta came from a more mechanical correction:

  • package.json, package-lock.json, and pnpm-lock.yaml stopped being invisible,
  • Stage 3 stopped saying "no dependency/provenance manifest detected,"
  • and Stage 4 stopped undercounting replication structure that was obviously there.

That is what I mean by "blind spot removal" rather than score drift.


Why that matters

This is the kind of change that sounds small in a changelog but large in practice.

Because it changes the relationship between the tool and the developer reading it.

A scanner earns the right to say "this repo is weak on provenance" only after it can correctly see the basic surfaces that exist in the target stack.

That correction also made later report outputs more believable.

When B1 moved from 0 to 15 in affected repositories, that was not "score drift." It was the removal of a blind spot.

And that distinction is exactly why audit tools need explicit versioned rationale.

Without it, every score movement looks arbitrary.


2. Problem: The warning lanes were doing too many jobs at once

Dedicated warning lanes in STEM BIO-AI showing C4, C5, and C6 semantic separation

Before the split, it helps to read C1–C6 as code-integrity lanes.

They are not general AI risk categories. They are reviewer-facing signals that tell you what kind of repository weakness the scanner found, and where to inspect next.

Lane What it means in STEM BIO-AI What a reviewer should inspect
C1 Hardcoded credential signals exposed API keys, cloud keys, tokens, or credential-like patterns
C2 Dependency pinning and external-service fragility loose dependency ranges, missing exact pins, fragile external service assumptions
C3 Deprecated patient-adjacent paths legacy, archive, or deprecated folders that still contain patient or clinical-adjacent patterns
C4 Fail-open exception handling except: pass, except Exception: pass, silent fallbacks, or code paths where errors can disappear
C5 Compliance and clinical-boundary integrity unsupported HIPAA, compliance, clinical-safe, self-hosted, or regulatory-adjacent claims
C6 Mock-auth or no-auth local/self-host trust boundaries auto-login, mock authentication, no-auth flows, or weak local trust-boundary assumptions

That table matters because C4, C5, and C6 are not interchangeable.

A fail-open exception is not the same problem as an unsupported compliance claim.

And an unsupported compliance claim is not the same problem as a mock-auth self-host boundary.

That distinction became important once the report started surfacing more nuanced governance signals.

The old C4 lane had started life as a code-oriented fail-open/exception surface.

But as the scanner got better at spotting unsupported compliance language and boundary failures, more and more signals were being interpreted near that same lane.

That made the result harder to read.

If a reviewer sees:

C4_exception_handling_clinical_adjacent_paths: WARN

they should be able to infer the remediation class immediately.

They should know to inspect executable control flow.

They should not have to wonder whether the warning is actually about a README compliance claim, a missing clinical boundary, or a mock-auth local path.

Once one lane starts carrying all of those meanings, the ID stops doing its job.

This is a common failure mode in rule systems.

At first it feels efficient:

  • one warning lane,
  • one bucket,
  • multiple related issues.

Then a few releases later the bucket becomes a junk drawer.

That is exactly what had to be prevented here.


What changed in 1.7.7 and 1.7.8

The solution was to split the lane cleanly:

  • C4 stayed reserved for executable fail-open exception behavior
  • C5 was introduced for unsupported compliance or boundary-integrity claims
  • C6 was introduced for mock-auth, auto-login, or no-auth self-host/local trust-boundary signals

This was more than renaming.

It made the model of the problem cleaner:

  • C4 is code-path failure semantics
  • C5 is governance/claim integrity
  • C6 is trust-boundary collapse in local or self-host flows

That distinction matters to developers because those are different remediation classes.

If a repository triggers C4, you inspect executable control flow.
If it triggers C5, you inspect public claim surfaces and supporting governance evidence.
If it triggers C6, you inspect local auth and trust-boundary design.

One warning label should not try to be all three.

The more interesting case is when two of those lanes fire together.

A repository can claim something like "HIPAA-ready self-hosting" at the README layer and also expose a mock-auth or auto-login local path.

That is not one problem.

It is two related problems:

  • C5 says the claim surface is overstating governance integrity
  • C6 says the local trust boundary is weaker than the claim suggests

That is exactly why the split matters.

If those two findings collapse into one bucket, the reviewer loses both remediation clarity and causal ordering.

If they stay separate, the report can say:

  1. the public claim is weak,
  2. the local boundary is weak,
  3. and both together make the repository easier to over-trust.

The code insight

This is one of those places where good audit tooling starts looking more like good static analysis design.

A useful warning family is not just one that catches things.

It is one that stays semantically stable across releases.

That is why this split mattered:

it was not just about improving recall.

It was about preserving interpretability under growth.

Once a detector ID becomes ambiguous, your historical comparisons become weaker.

And once historical comparisons become weaker, your audit system starts losing its memory.

That is a bigger problem than one missed warning.


3. Problem: The report could still be correct and yet hard to trust

A repository scanner does not end its life in JSON.

It ends up in:

  • Markdown
  • HTML
  • PDF
  • demos
  • governance reviews
  • screenshots
  • and social arguments

That means the output architecture matters almost as much as the scoring logic.

And there were two places where this became obvious.


First: AIRI numbers needed explanation, not just display

AIRI numbers needed explanation

Earlier versions could show AIRI coverage as a count, but not always make it obvious why a covered risk appeared.

That is a problem.

Because a number like 7 / 32 looks precise.

But precision without causal explanation is fragile.

Developers do not just want to know that a risk mapped.
They want to know:

  • which detector triggered it,
  • why that detector maps to that AIRI risk,
  • and what boundary still remains around that mapping.

So the AIRI layer had to become more explicit.

That is where mapping_details mattered.

Covered AIRI rows now carry bounded reasoning objects that can say, in effect:

  • detector ID
  • mapping justification
  • trigger reason

That is a much stronger artifact than a bare coverage count.

It turns AIRI from a visual add-on into an inspectable vocabulary layer.

In practice the object now looks more like this:

{
  "id": "24.01.03",
  "title": "Safe exploration problem with widely deployed AI assistants",
  "covered_by": ["C5_compliance_boundary_integrity"],
  "mapping_details": [
    {
      "detector_id": "C5_compliance_boundary_integrity",
      "mapping_justification": "Weak compliance and clinical-boundary integrity can cause users to over-trust unsafe exploration in clinical-adjacent contexts.",
      "trigger_reason": "Unsupported legal/compliance claim surfaced in boundary-integrity lane."
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

That matters because the AIRI layer no longer asks the reviewer to trust a number alone.

It now gives the reviewer a bounded reasoning object to inspect.


Second: The packets themselves needed re-architecture

Artifact architecture showing brief, standard, and full evidence packet tiers across output surfaces

The PDF tiers had also drifted into an awkward shape.

The old packet boundaries were no longer matching the actual content density:

  • Stage 4 could disappear or feel collapsed
  • the closeout pages could become overcrowded
  • and "5-page detailed packet" could stop meaning what users expected

That led to a cleaner packet model:

  • level 1 = brief 1p
  • level 2 = standard 5p
  • level 3 = full 7p

And just as importantly:

  • the default CLI path moved to level 3

It is a statement about what the project now considers the normal artifact.

The normal artifact is no longer the brief scan.
It is the full evidence packet.


Why that matters

This is where the project moved from "scanner" toward "audit architecture."

A scanner can stop at a result.

An audit architecture has to preserve meaning across surfaces.

That means:

  • JSON must be canonical
  • HTML must be navigable
  • PDFs must honor real packet boundaries
  • and the same warning semantics must survive in all of them

That is why these changes matter to developers.

They are part of the correctness story.

If the why disappears when the result becomes a report, the audit object was never complete to begin with.


The hidden pattern behind all three changes

These releases can look like a mixed bag:

  • JS manifest support
  • legal/compliance claim surfacing
  • external dependency risk
  • C4/C5/C6 split
  • AIRI reasoning
  • packet restructuring
  • demo/output alignment

But there is a single pattern underneath them:

the system became less willing to let ambiguity hide inside a convenient surface.

That showed up in three ways:

  1. a manifest should count if it exists
  2. a warning lane should mean one thing
  3. a risk mapping should explain itself

That may sound almost obvious.

But a lot of tools never make it that far.

They accumulate clever features faster than they reduce ambiguity.

This line of work did the opposite.

It made *the system stricter about what its outputs are allowed to imply.
*

That is a more durable path.


The more interesting lesson

The most useful thing about 1.7.6 through 1.7.8 is not that STEM BIO-AI became "smarter."

It is that it became harder to misread.

That is a better goal for audit tooling.

Especially now.

Because in a world increasingly full of fluent agent outputs, the differentiator is not whether a tool can generate a plausible narrative.

It is whether the narrative stays tethered to inspectable structure when the repository is messy, cross-stack, overclaimed, or partially misleading.

That is where this release line got better.

Not by pretending to know more than it does.

But by making its own boundaries clearer.


What I would tell developers evaluating this line

What I would tell developers evaluating this line

If you only look at the release notes, you might think:

  • better AIRI
  • more warnings
  • nicer reports

That is true, but too shallow.

The real changes are:

  • the scanner is less Python-centric than it was
  • the warning taxonomy is more semantically stable than it was
  • the artifacts are more inspectable than they were

That combination matters more than any one score change.

It means the tool is becoming less of a clever repo grader and more of a reliable evidence instrument.

That is the direction I care about.

Because once the repository is politically messy, clinically adjacent, or governance-sensitive, "good-enough automation" is not enough.

The system has to show its work.

These versions got noticeably better at doing that.

A Reiable Edivdence Instrument for the Messy Reality


Try It

pip install stem-ai
stem /path/to/repo

Enter fullscreen mode Exit fullscreen mode

If you want the full packet explicitly:

stem scan /path/to/repo --level 3 --format all --explain

Enter fullscreen mode Exit fullscreen mode

The default path now lands on the full evidence packet, and that is the point.

In audit tooling, the serious path should not require an extra flag.


See the Artifact

If you want to inspect the actual artifact shape behind this release line, these two public outputs are the best reference:

stem-bio-ai report

The point of 1.7.8 is not just that the scanner scores the repository differently.

It is that the same result now survives translation into JSON, Markdown, HTML, and a full review packet without losing too much meaning along the way.