-
-## Lighthouse PageSpeed Insights
-
-[](https://pagespeed.web.dev/report?url=https%3A%2F%2Falshedivat.github.io%2Fal-folio%2F&form_factor=desktop)
-
-## Table Of Contents
-
-- [al-folio](#al-folio)
- - [User community](#user-community)
- - [Lighthouse PageSpeed Insights](#lighthouse-pagespeed-insights)
- - [Table Of Contents](#table-of-contents)
- - [Getting started](#getting-started)
- - [Installation](#installation)
- - [Local setup using Docker (Recommended on Windows)](#local-setup-using-docker-recommended-on-windows)
- - [Local Setup (Standard)](#local-setup-standard)
- - [Deployment](#deployment)
- - [Upgrading from a previous version](#upgrading-from-a-previous-version)
- - [FAQ](#faq)
- - [Features](#features)
- - [Publications](#publications)
- - [Collections](#collections)
- - [Layouts](#layouts)
- - [The iconic style of Distill](#the-iconic-style-of-distill)
- - [Full support for math \& code](#full-support-for-math--code)
- - [Photos](#photos)
- - [Other features](#other-features)
- - [GitHub's repositories and user stats](#githubs-repositories-and-user-stats)
- - [Theming](#theming)
- - [Social media previews](#social-media-previews)
- - [Atom (RSS-like) Feed](#atom-rss-like-feed)
- - [Related posts](#related-posts)
- - [Contributing](#contributing)
- - [Maintainers](#maintainers)
- - [License](#license)
-
-## Getting started
-
-Want to learn more about Jekyll? Check out [this tutorial](https://www.taniarascia.com/make-a-static-website-with-jekyll/).
-Why Jekyll? Read [Andrej Karpathy's blog post](https://karpathy.github.io/2014/07/01/switching-to-jekyll/)!
-
-### Installation
-
-For a hands-on walkthrough of al-folio installation, check out [this cool video tutorial](https://www.youtube.com/watch?v=g6AJ9qPPoyc) by one of the community members! 🎬 🍿
-
-The preferred way of using this template is by clicking in [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template#creating-a-repository-from-a-template) above the file list.
-Then, create a new repository at `github.com:/`. If you plan to upload your site to `.github.io`,
-note that the name of your repository must be `.github.io` or `.github.io`, as stated in the [GitHub pages docs](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites).
-For more information on how to deploy your site, check the [Deployment](#deployment) section below. After you created your new repository, just download it to your machine:
-
-```bash
-$ git clone git@github.com:/.git
-$ cd
-```
-
----
-
-#### Local setup using Docker (Recommended on Windows)
-
-You need to take the following steps to get `al-folio` up and running in your local machine:
-
-- First, install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/).
-- Finally, run the following command that will pull a pre-built image from DockerHub and will run your website.
-
-```bash
-$ docker-compose up
-```
-
-Note that when you run it for the first time, it will download a docker image of size 300MB or so.
-
-Now, feel free to customize the theme however you like (don't forget to change the name!). After you are done, you can use the same command (`docker-compose up`) to render the webpage with all you changes. Also, make sure to commit your final changes.
-
-> To change port number, you can edit `docker-compose.yml` file.
-
-(click to expand) Build your own docker image:
-
-> Note: this approach is only necessary if you would like to build an older or very custom version of al-folio.
-
-Build and run a new docker image using:
-
-```bash
-$ docker-compose -f docker-local.yml up
-```
-
-> If you want to update jekyll, install new ruby packages, etc., all you have to do is build the image again using `--force-recreate` argument at the end of previous command! It will download ruby and jekyll and install all ruby packages again from scratch.
-
-
-
----
-
-#### Local Setup (Standard)
-
-Assuming you have [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed on your system (*hint: for ease of managing ruby gems, consider using [rbenv](https://github.com/rbenv/rbenv)*).
-
-```bash
-$ bundle install
-$ bundle exec jekyll serve --lsi
-```
-
-Now, feel free to customize the theme however you like (don't forget to change the name!).
-After you are done, **commit** your final changes.
-
----
-
-#### Deployment
-
-Deploying your website to [GitHub Pages](https://pages.github.com/) is the most popular option.
-Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository! :sparkles:
-
-**For personal and organization webpages:**
-
-1. The name of your repository **MUST BE** `.github.io` or `.github.io`.
-2. In `_config.yml`, set `url` to `https://.github.io` and leave `baseurl` empty.
-3. Set up automatic deployment of your webpage (see instructions below).
-4. Make changes, commit, and push!
-5. After deployment, the webpage will become available at `.github.io`.
-
-**For project pages:**
-
-1. In `_config.yml`, set `url` to `https://.github.io` and `baseurl` to `//`.
-2. Set up automatic deployment of your webpage (see instructions below).
-3. Make changes, commit, and push!
-4. After deployment, the webpage will become available at `.github.io//`.
-
-**To enable automatic deployment:**
-
-1. Click on **Actions** tab and **Enable GitHub Actions**; do not worry about creating any workflows as everything has already been set for you.
-2. Go to Settings -> Actions -> General -> Workflow permissions, and give **Read and write permissions** to GitHub Actions
-3. Make any other changes to your webpage, commit, and push. This will automatically trigger the **Deploy** action.
-4. Wait for a few minutes and let the action complete. You can see the progress in the **Actions** tab. If completed successfully, in addition to the `master` branch, your repository should now have a newly built `gh-pages` branch.
-5. Finally, in the **Settings** of your repository, in the Pages section, set the branch to `gh-pages` (**NOT** to `master`). For more details, see [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source).
-
-If you keep your site on another branch, open `.github/workflows/deploy.yml` **on the branch you keep your website on** and change on->push->branches and on->pull\_request->branches to the branch you keep your website on. This will trigger the action on pulls/pushes on that branch. The action will then deploy the website on the branch it was triggered from.
-
-(click to expand) Manual deployment to GitHub Pages:
-
-If you need to manually re-deploy your website to GitHub pages, go to Actions, click "Deploy" in the left sidebar, then "Run workflow."
-
-
-
-(click to expand) Deployment to another hosting server (non GitHub Pages):
-
-If you decide to not use GitHub Pages and host your page elsewhere, simply run:
-
-```bash
-$ bundle exec jekyll build --lsi
-```
-
-which will (re-)generate the static webpage in the `_site/` folder.
-Then simply copy the contents of the `_site/` directory to your hosting server.
-
-**Note:** Make sure to correctly set the `url` and `baseurl` fields in `_config.yml` before building the webpage. If you are deploying your webpage to `your-domain.com/your-project/`, you must set `url: your-domain.com` and `baseurl: /your-project/`. If you are deploying directly to `your-domain.com`, leave `baseurl` blank.
-
-
-
-(click to expand) Deployment to a separate repository (advanced users only):
-
-**Note:** Do not try using this method unless you know what you are doing (make sure you are familiar with [publishing sources](https://help.github.com/en/github/working-with-github-pages/about-github-pages#publishing-sources-for-github-pages-sites)). This approach allows to have the website's source code in one repository and the deployment version in a different repository.
-
-Let's assume that your website's publishing source is a `publishing-source` subdirectory of a git-versioned repository cloned under `$HOME/repo/`.
-For a user site this could well be something like `$HOME/.github.io`.
-
-Firstly, from the deployment repo dir, checkout the git branch hosting your publishing source.
-
-Then from the website sources dir (commonly your al-folio fork's clone):
-
-```bash
-$ bundle exec jekyll build --lsi --destination $HOME/repo/publishing-source
-```
-
-This will instruct jekyll to deploy the website under `$HOME/repo/publishing-source`.
-
-**Note:** Jekyll will clean `$HOME/repo/publishing-source` before building!
-
-The quote below is taken directly from the [jekyll configuration docs](https://jekyllrb.com/docs/configuration/options/):
-
-> Destination folders are cleaned on site builds
->
-> The contents of `` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `` configuration directive.
->
-> Do not use an important location for ``; instead, use it as a staging area and copy files from there to your web server.
-
-If `$HOME/repo/publishing-source` contains files that you want jekyll to leave untouched, specify them under `keep_files` in `_config.yml`.
-In its default configuration, al-folio will copy the top-level `README.md` to the publishing source. If you want to change this behavior, add `README.md` under `exclude` in `_config.yml`.
-
-**Note:** Do _not_ run `jekyll clean` on your publishing source repo as this will result in the entire directory getting deleted, irrespective of the content of `keep_files` in `_config.yml`.
-
-
-
----
-
-#### Upgrading from a previous version
-
-If you installed **al-folio** as described above, you can configure a [GitHub action](https://github.com/AndreasAugustin/actions-template-sync) to automatically sync your repository with the latest version of the theme.
-
-Go to Settings -> Actions -> General -> Workflow permissions, give Read and write permissions to GitHub Actions, check "Allow GitHub Actions to create and approve pull requests", and save your changes.
-
-Then go to Actions -> New workflow -> set up a workflow yourself, setup the following workflow and commit your changes:
-
-```yaml
-name: Sync from template
-on:
- # cronjob trigger
- schedule:
- - cron: "0 0 1 * *"
- # manual trigger
- workflow_dispatch:
-jobs:
- repo-sync:
- runs-on: ubuntu-latest
- steps:
- # To use this repository's private action, you must check out the repository
- - name: Checkout
- uses: actions/checkout@v3
- - name: actions-template-sync
- uses: AndreasAugustin/actions-template-sync@v0.7.3
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- source_repo_path: alshedivat/al-folio
- upstream_branch: master
-```
-
-You will receive a pull request within your repository if there are some changes available in the template.
-
-Another option is to manually update your code by following the steps below:
-
-```bash
-# Assuming the current directory is
-$ git remote add upstream https://github.com/alshedivat/al-folio.git
-$ git fetch upstream
-$ git rebase v0.9.0
-```
-
-If you have extensively customized a previous version, it might be trickier to upgrade.
-You can still follow the steps above, but `git rebase` may result in merge conflicts that must be resolved.
-See [git rebase manual](https://help.github.com/en/github/using-git/about-git-rebase) and how to [resolve conflicts](https://help.github.com/en/github/using-git/resolving-merge-conflicts-after-a-git-rebase) for more information.
-If rebasing is too complicated, we recommend re-installing the new version of the theme from scratch and port over your content and changes from the previous version manually.
-
----
-
-### FAQ
-
-Here are some frequently asked questions.
-If you have a different question, please ask using [Discussions](https://github.com/alshedivat/al-folio/discussions/categories/q-a).
-
-1. **Q:** After I create a new repository from this template and setup the repo, I get a deployment error.
- Isn't the website supposed to correctly deploy automatically?
- **A:** Yes, if you are using release `v0.3.5` or later, the website will automatically and correctly re-deploy right after your first commit.
- Please make some changes (e.g., change your website info in `_config.yml`), commit, and push.
- Make sure to follow [deployment instructions](https://github.com/alshedivat/al-folio#deployment) in the previous section.
- (Relevant issue: [209](https://github.com/alshedivat/al-folio/issues/209#issuecomment-798849211).)
-
-2. **Q:** I am using a custom domain (e.g., `foo.com`).
- My custom domain becomes blank in the repository settings after each deployment.
- How do I fix that?
- **A:** You need to add `CNAME` file to the `master` or `source` branch of your repository.
- The file should contain your custom domain name.
- (Relevant issue: [130](https://github.com/alshedivat/al-folio/issues/130).)
-
-3. **Q:** My webpage works locally.
- But after deploying, it is not displayed correctly (CSS and JS is not loaded properly).
- How do I fix that?
- **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`.
- Set `url` to `https://.github.io` or to `https://` if you are using a custom domain.
- If you are deploying a personal or organization website, leave `baseurl` blank.
- If you are deploying a project page, set `baseurl: //`.
-
-4. **Q:** Atom feed doesn't work. Why?
-
- **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`.
- RSS Feed plugin works with these correctly set up fields: `title`, `url`, `description` and `author`.
- Make sure to fill them in an appropriate way and try again.
-
-5. **Q:** My site doesn't work when I enable `related_blog_posts`. Why?
- **A:** This is probably due to the [classifier reborn](https://github.com/jekyll/classifier-reborn) plugin, which is used to calculate
- related posts. If the error states `Liquid Exception: Zero vectors can not be normalized...`, it means that it could not calculate related
- posts for a specific post. This is usually caused by [empty or minimal blog posts](https://github.com/jekyll/classifier-reborn/issues/64)
- without meaningful words (i.e. only [stop words](https://en.wikipedia.org/wiki/Stop_words)) or even
- [specific characters](https://github.com/jekyll/classifier-reborn/issues/194) you used in your posts. Also, the calculus for similar posts are
- made for every `post`, which means every page that uses `layout: post`, including the announcements. To change this behavior, simply add
- `related_posts: false` to the front matter of the page you don't want to display related posts on.
-
-## Features
-
-### Publications
-
-Your publications' page is generated automatically from your BibTex bibliography.
-Simply edit `_bibliography/papers.bib`.
-You can also add new `*.bib` files and customize the look of your publications however you like by editing `_pages/publications.md`.
-
-
-
-(click to expand) Author annotation:
-
-In publications, the author entry for yourself is identified by string array `scholar:last_name` and string array `scholar:first_name` in `_config.yml`:
-
-```yaml
-scholar:
- last_name: [Einstein]
- first_name: [Albert, A.]
-```
-
-If the entry matches one form of the last names and the first names, it will be underlined.
-Keep meta-information about your co-authors in `_data/coauthors.yml` and Jekyll will insert links to their webpages automatically.
-The co-author data format in `_data/coauthors.yml` is as follows,
-
-```yaml
-"Adams":
- - firstname: ["Edwin", "E.", "E. P.", "Edwin Plimpton"]
- url: https://en.wikipedia.org/wiki/Edwin_Plimpton_Adams
-
-"Podolsky":
- - firstname: ["Boris", "B.", "B. Y.", "Boris Yakovlevich"]
- url: https://en.wikipedia.org/wiki/Boris_Podolsky
-
-"Rosen":
- - firstname: ["Nathan", "N."]
- url: https://en.wikipedia.org/wiki/Nathan_Rosen
-
-"Bach":
- - firstname: ["Johann Sebastian", "J. S."]
- url: https://en.wikipedia.org/wiki/Johann_Sebastian_Bach
-
- - firstname: ["Carl Philipp Emanuel", "C. P. E."]
- url: https://en.wikipedia.org/wiki/Carl_Philipp_Emanuel_Bach
-```
-
-If the entry matches one of the combinations of the last names and the first names, it will be highlighted and linked to the url provided.
-
-
-
-(click to expand) Buttons (through custom bibtex keywords):
-
-There are several custom bibtex keywords that you can use to affect how the entries are displayed on the webpage:
-
-- `abbr`: Adds an abbreviation to the left of the entry. You can add links to these by creating a venue.yaml-file in the _data folder and adding entries that match.
-- `abstract`: Adds an "Abs" button that expands a hidden text field when clicked to show the abstract text
-- `arxiv`: Adds a link to the Arxiv website (Note: only add the arxiv identifier here - the link is generated automatically)
-- `bibtex_show`: Adds a "Bib" button that expands a hidden text field with the full bibliography entry
-- `html`: Inserts an "HTML" button redirecting to the user-specified link
-- `pdf`: Adds a "PDF" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
-- `supp`: Adds a "Supp" button to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
-- `blog`: Adds a "Blog" button redirecting to the specified link
-- `code`: Adds a "Code" button redirecting to the specified link
-- `poster`: Adds a "Poster" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
-- `slides`: Adds a "Slides" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
-- `website`: Adds a "Website" button redirecting to the specified link
-- `altmetric`: Adds an [Altmetric](https://www.altmetric.com/) badge (Note: if DOI is provided just use `true`, otherwise only add the altmetric identifier here - the link is generated automatically)
-- `dimensions`: Adds a [Dimensions](https://www.dimensions.ai/) badge (Note: if DOI or PMID is provided just use `true`, otherwise only add the Dimensions' identifier here - the link is generated automatically)
-
-You can implement your own buttons by editing the bib.html file.
-
-
-
----
-
-### Collections
-
-This Jekyll theme implements `collections` to let you break up your work into categories.
-The theme comes with two default collections: `news` and `projects`.
-Items from the `news` collection are automatically displayed on the home page.
-Items from the `projects` collection are displayed on a responsive grid on projects page.
-
-
-
-You can easily create your own collections, apps, short stories, courses, or whatever your creative work is.
-To do this, edit the collections in the `_config.yml` file, create a corresponding folder, and create a landing page for your collection, similar to `_pages/projects.md`.
-
----
-
-### Layouts
-
-**al-folio** comes with stylish layouts for pages and blog posts.
-
-#### The iconic style of Distill
-
-The theme allows you to create blog posts in the [distill.pub](https://distill.pub/) style:
-
-
-
-For more details on how to create distill-styled posts using `` tags, please refer to [the example](https://alshedivat.github.io/al-folio/blog/2021/distill/).
-
-#### Full support for math & code
-
-**al-folio** supports fast math typesetting through [MathJax](https://www.mathjax.org/) and code syntax highlighting using [GitHub style](https://github.com/jwarby/jekyll-pygments-themes):
-
-
-
-
-
-
-#### Photos
-
-Photo formatting is made simple using [Bootstrap's grid system](https://getbootstrap.com/docs/4.4/layout/grid/).
-Easily create beautiful grids within your blog posts and project pages:
-
-
-
----
-
-### Other features
-
-#### GitHub's repositories and user stats
-
-**al-folio** uses [github-readme-stats](https://github.com/anuraghazra/github-readme-stats) and [github-profile-trophy](https://github.com/ryo-ma/github-profile-trophy)
-to display GitHub repositories and user stats on the `/repositories/` page.
-
-Edit the `_data/repositories.yml` and change the `github_users` and `github_repos` lists to include your own GitHub profile and repositories to the `/repositories/` page.
-
-You may also use the following codes for displaying this in any other pages.
-
-```html
-
-{% if site.data.repositories.github_users %}
-
- {% for user in site.data.repositories.github_users %}
- {% include repository/repo_user.html username=user %}
- {% endfor %}
-
-{% endif %}
-
-
-{% if site.repo_trophies.enabled %}
-{% for user in site.data.repositories.github_users %}
- {% if site.data.repositories.github_users.size > 1 %}
-
{{ user }}
- {% endif %}
-
- {% include repository/repo_trophies.html username=user %}
-
- {% for repo in site.data.repositories.github_repos %}
- {% include repository/repo.html repository=repo %}
- {% endfor %}
-
-{% endif %}
+```sh
+npm ci
+npm run dev
```
-#### Theming
-
-A variety of beautiful theme colors have been selected for you to choose from.
-The default is purple, but you can quickly change it by editing the
-`--global-theme-color` variable in the `_sass/_themes.scss` file.
-Other color variables are listed there as well.
-The stock theme color options available can be found at `_sass/variables.scss`.
-You can also add your own colors to this file assigning each a name for ease of
-use across the template.
-
-#### Social media previews
-
-**al-folio** supports preview images on social media.
-To enable this functionality you will need to set `serve_og_meta` to `true` in your `_config.yml`.
-Once you have done so, all your site's pages will include Open Graph data in the HTML head element.
-
-You will then need to configure what image to display in your site's social media previews.
-This can be configured on a per-page basis, by setting the `og_image` page variable.
-If for an individual page this variable is not set, then the theme will fall back to a site-wide `og_image` variable, configurable in your `_config.yml`.
-In both the page-specific and site-wide cases, the `og_image` variable needs to hold the URL for the image you wish to display in social media previews.
-
-#### Atom (RSS-like) Feed
-
-It generates an Atom (RSS-like) feed of your posts, useful for Atom and RSS readers.
-The feed is reachable simply by typing after your homepage `/feed.xml`.
-E.g. assuming your website mountpoint is the main folder, you can type `yourusername.github.io/feed.xml`
-
-#### Related posts
-
-By default, there will be a related posts section on the bottom of the blog posts.
-These are generated by selecting the `max_related` most recent posts that share at least `min_common_tags` tags with the current post.
-If you do not want to display related posts on a specific post, simply add `related_posts: false` to the front matter of the post.
-If you want to disable it for all posts, simply set `enabled` to false in the `related_blog_posts` section in `_config.yml`.
-
-## Contributing
-
-Contributions to al-folio are very welcome!
-Before you get started, please take a look at [the guidelines](CONTRIBUTING.md).
-
-If you would like to improve documentation, add your webpage to the list below, or fix a minor inconsistency or bug, please feel free to send a PR directly to `master`.
-For more complex issues/bugs or feature requests, please open an issue using the appropriate template.
-
-### Maintainers
-
-Our most active contributors are welcome to join the maintainers team.
-If you are interested, please reach out!
-
-
-
-
-
-
-
-
-
-
-
-## License
+Run `npm run verify` before release. Production builds exclude editorial drafts.
-The theme is available as open source under the terms of the [MIT License](https://github.com/alshedivat/al-folio/blob/master/LICENSE).
+- [Website maintenance and publishing](WEBSITE.md)
+- [Refinement plan](_planning/site-refinement-plan.md)
+- [Migration report](_planning/migration-report.md)
+- [Original al-folio documentation](_planning/legacy-theme-readme.md)
-Originally, **al-folio** was based on the [\*folio theme](https://github.com/bogoli/-folio) (published by [Lia Bogoev](https://liabogoev.com) and under the MIT license).
-Since then, it got a full re-write of the styles and many additional cool features.
+The original Jekyll content and assets remain available for reference. Only
+Astro's `dist/` output is deployed by the updated workflow.
diff --git a/WEBSITE.md b/WEBSITE.md
new file mode 100644
index 0000000000000..c459d77efea2a
--- /dev/null
+++ b/WEBSITE.md
@@ -0,0 +1,117 @@
+# Website maintenance
+
+The new site uses Astro static output. Original Jekyll source remains for reference
+and is not included in the generated website.
+
+## Current scope: academic homepage
+
+The homepage uses a compact biography followed by a linked research map. Its six
+selected publications are grouped into coding-agent evaluation, test oracles,
+AI-system testing, and AIOps. Edit `src/data/research.ts` to update map membership
+and publication groups together. The map describes thematic connections, not a
+timeline or technical dependency graph. Its layout becomes a vertical list on
+small screens; all links work without client-side JavaScript.
+
+The homepage and navigation prioritize academic identity, research, publications,
+service, and biography. Writing and education routes are retained for later work,
+but are not promoted in the academic navigation or homepage. Normal local preview
+should use `npm run dev` (without drafts).
+
+Research summaries and resource links live in `src/data/site.ts`; full citation
+metadata lives in `_bibliography/papers.bib`. Keep quantitative claims scoped to
+the cited paper's evaluation. Service records in `src/data/services.json` preserve
+all 20 original entries across 2021-2025, with an integration test against the
+original source. Add new service records to both the migration baseline and the
+dataset, or explicitly update the migration test when maintaining newer years.
+
+## Run and verify
+
+Use Node 24 LTS (minimum 22.12) and npm.
+
+```sh
+npm ci
+npm run dev
+npm run dev:drafts
+npm run verify
+npm run preview
+```
+
+Use either development command, not both on the same port. Normal development
+hides drafts; `dev:drafts` shows them with a visible editorial banner and noindex.
+Production builds always exclude drafts, including when CONTENT_PREVIEW is set.
+Astro 7 runs the dev server in the background. Use `npx astro dev stop` before
+switching preview modes; `npx astro dev logs` displays its logs.
+
+`verify` runs type checks, the static build, link and migration checks, draft
+isolation checks, and a publishing integration test in a temporary directory.
+The integration test renders both Markdown and MDX without changing local articles.
+
+## Write an article
+
+Create a stable filename under `src/content/writing/`. Its name becomes the URL.
+Use Markdown by default and MDX when an article needs a component.
+
+```yaml
+---
+title: 'A precise article title'
+description: 'What the reader will learn.'
+publishedAt: 2026-09-08
+language: en
+topics: [AI evaluation]
+audience: developers and research readers
+draft: true
+featured: false
+series: Evaluating AI in practice
+order: 3
+---
+```
+
+`series` and `order` are optional, but must be supplied together. Use distinct
+order values within a series. `updatedAt` describes a substantive revision.
+Review facts, references, examples, and resource links. Then set `draft: false`,
+select the publication date, and run `npm run verify`.
+Home shows up to two featured articles; Writing contains all released articles.
+RSS and sitemap use the same publication-date and draft restrictions.
+
+Future-dated posts require a new build on or after their publication date. This
+repository does not schedule future publishing automatically. Articles linked
+from a released article must also be published; broken links fail verification.
+
+The two initial English explainers are editorial drafts prepared during the
+redesign, not existing published work. Review them before release.
+
+## Update research and background
+
+- `_bibliography/papers.bib`: publication records, resource URLs, citation keys.
+- `src/data/site.ts`: profile metadata and three research highlights.
+- `src/data/services.json`: migrated academic service records.
+- `_news/*.md` and `_talks/*.md`: retained announcement and talk sources.
+- `src/pages/about.astro` and `src/pages/teaching.astro`: background and assistantships.
+- `src/pages/education.astro`: learning resource and series placement.
+
+Bibliography keys remain publication anchors. The unused legacy APS string
+declaration was removed; the lightweight parser expects explicit field values
+rather than BibTeX string macros. Existing PDF paths remain unchanged.
+`prepare:assets` copies PDFs, portrait and legacy icon, exports clean BibTeX,
+and generates a PNG social card from `public/social-card.svg`.
+
+## Release and rollback
+
+Review the site and editorial drafts separately. Production builds exclude drafts.
+
+The workflow validates pull requests and uploads an artifact without publishing
+them. Pushes or manual runs on master/main deploy verified `dist/` output using
+GitHub's official upload-pages-artifact and deploy-pages actions. Repository Pages
+settings must use GitHub Actions as the build source; the github-pages environment
+allows the master branch to deploy.
+
+The previous deployed gh-pages commit is
+`5ad5ce2f6b855d3b6ececc9be7090c22e14c2fe6`; the branch is retained for rollback.
+For rollback, prepare a revert PR for the migration, including its workflow, or
+redeploy the retained known-good static artifact through the normal deployment
+process. Avoid force-pushing or resetting shared history. The source baseline for
+this redesign is 5b12a018464201cee4c0b2bf148779c425289b0d. To restore the legacy
+site immediately, switch Pages back to branch publishing from gh-pages at its
+retained commit. Reverting source code alone does not change the Pages build source.
+
+See `_planning/migration-report.md` for retained routes and editorial follow-ups.
diff --git a/_bibliography/papers.bib b/_bibliography/papers.bib
index fb4a511a7aaa3..f48f570c5e003 100644
--- a/_bibliography/papers.bib
+++ b/_bibliography/papers.bib
@@ -1,31 +1,34 @@
---
---
-@string{aps = {American Physical Society,}}
-
-
@article{yu2026sweabs,
abbr={ICML},
title={SWE-ABS: Adversarial Benchmark Strengthening Exposes Inflated Success Rates on Test-based Benchmark},
- author={Yu, Boxi and others},
+ author={Yu, Boxi and Cao, Yang and Zhang, Yuzhong and Lin, Liting and Xu, Junjielong and Zhong, Zhiqing and Xu, Qinghua and Wang, Guancheng and Cao, Jialun and Cheung, Shing-Chi and He, Pinjia and Briand, Lionel},
journal={ICML'26: International Conference on Machine Learning},
year={2026},
selected={true},
- topic={CodeAgents}
+ topic={CodeAgents},
+ arxiv={2603.00520},
+ url={https://arxiv.org/abs/2603.00520},
+ pdf={https://arxiv.org/pdf/2603.00520}
}
-@article{yu2025utboost,
+@inproceedings{yu2025utboost,
abbr={ACL},
title={UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench},
author={Boxi Yu and Yuxuan Zhu and Pinjia He and Daniel Kang},
year={2025},
+ booktitle={Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)},
+ pages={3762--3774},
+ doi={10.18653/v1/2025.acl-long.189},
selected={true},
topic={CodeAgents},
arxiv={2506.09289},
code={https://github.com/CUHK-Shenzhen-SE/UTBoost},
primaryClass={cs.SE},
- url={https://arxiv.org/abs/2506.09289},
- pdf={https://arxiv.org/pdf/2506.09289}
+ url={https://aclanthology.org/2025.acl-long.189/},
+ pdf={https://aclanthology.org/2025.acl-long.189.pdf}
}
@article{yu2023Retro,
@@ -43,7 +46,7 @@ @article{yu2023Retro
@article{cao2025,
abbr={ICML Position},
- title={How Should We Build A Benchmark? Revisiting 274 Code-Related Benchmarks For LLMs},
+ title={Code Benchmarks Should Prioritize Rigor, Reliability, and Reproducibility},
author={Jialun Cao and Yuk-Kit Chan and Zixuan Ling and Wenxuan Wang and Shuqing Li and Mingwei Liu and Ruixi Qiao and Yuting Han and Chaozheng Wang and Boxi Yu and Pinjia He and Shuai Wang and Zibin Zheng and Michael R. Lyu and Shing-Chi Cheung},
journal={ICML Position},
year={2026},
@@ -59,6 +62,8 @@ @article{cao2025
@article{zhong2025deprecation,
abbr={ICSE},
title={An Empirical Study on Package-Level Deprecation in Python Ecosystem},
+ doi={10.1109/ICSE55347.2025.00046},
+ url={https://doi.org/10.1109/ICSE55347.2025.00046},
author={Zhong, Zhiqing and He, Shilin and Wang, Haoxuan and Yu, Boxi and Yang, Haowen and He, Pinjia},
journal={ICSE'25: International Conference on Software Engineering},
year={2025},
@@ -94,6 +99,8 @@ @article{yu2024dspyg
@article{mang2024EQR,
abbr={ICSE},
title={Testing Graph Database Systems via Equivalent Query Rewriting},
+ doi={10.1145/3597503.3639200},
+ url={https://doi.org/10.1145/3597503.3639200},
author={Mang, Qiuyang and Fang, Aoyang and Yu, Boxi and Chen, Hanfei and He, Pinjia},
journal={ICSE'24: International Conference on Software Engineering},
year={2024},
@@ -123,7 +130,7 @@ @article{yu2023tin
author={Yu, Boxi and Hu, Yiyan and Mang, Qiuyang and Hu, Wenhan and He, Pinjia},
journal={ESEC/FSE'23: Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering},
pdf={https://arxiv.org/pdf/2308.07937.pdf},
- code={https://github.com/RobustNLP/TestIC},
+ code={https://github.com/RobustNLP/TestNER},
year={2023},
selected={true},
topic={AutomatedTesting},
@@ -151,7 +158,7 @@ @inproceedings{yu2023rome
series = {ISSTA 2023},
selected={true},
topic={AutomatedTesting},
- code={https://github.com/RobustNLP/TestNER},
+ code={https://github.com/RobustNLP/TestIC},
html={https://dl.acm.org/doi/abs/10.1145/3597926.3598094},
pdf={https://arxiv.org/pdf/2306.02228.pdf},
slides={Rome_slides.pdf}
diff --git a/_config.yml b/_config.yml
index 7453f6a35a25c..1208b446ddc3d 100644
--- a/_config.yml
+++ b/_config.yml
@@ -6,7 +6,7 @@ title: blank # the website title (if blank, full name will be used instead)
first_name: Boxi
middle_name:
last_name: Yu
-email: boxiyu@link.cuhk.edu.cn
+email: boxi.yu@lero.ie
description: > # the ">" symbol means to ignore newlines until "footer_text:"
Academic homepage of Boxi Yu, Senior Research Fellow at Lero.
footer_text: >
diff --git a/_planning/legacy-theme-readme.md b/_planning/legacy-theme-readme.md
new file mode 100644
index 0000000000000..eae151a7c0f1d
--- /dev/null
+++ b/_planning/legacy-theme-readme.md
@@ -0,0 +1,661 @@
+# al-folio
+
+[maintainers]: https://img.shields.io/badge/maintainers-4-success.svg 'Number of maintainers'
+
+
+[](https://github.com/alshedivat/al-folio/actions/workflows/deploy.yml)
+[](https://alshedivat.github.io/al-folio/)
+[](https://github.com/alshedivat/al-folio/graphs/contributors/)
+[![Maintainers][maintainers]](#maintainers)
+[](https://github.com/alshedivat/al-folio/releases/latest)
+[](https://github.com/alshedivat/al-folio/blob/master/LICENSE)
+[](https://github.com/alshedivat/al-folio)
+[](https://github.com/alshedivat/al-folio/fork)
+
+[](https://hub.docker.com/r/amirpourmand/al-folio)
+[](https://hub.docker.com/r/amirpourmand/al-folio)
+[](https://hub.docker.com/r/amirpourmand/al-folio)
+
+A simple, clean, and responsive [Jekyll](https://jekyllrb.com/) theme for academics.
+If you like the theme, give it a star!
+
+[](https://alshedivat.github.io/al-folio/)
+
+## User community
+
+The vibrant community of **al-folio** users is growing!
+Academics around the world use this theme for their homepages, blogs, lab pages, as well as webpages for courses, workshops, conferences, meetups, and more.
+Check out the community webpages below.
+Feel free to add your own page(s) by sending a PR.
+
+
+
+## Lighthouse PageSpeed Insights
+
+[](https://pagespeed.web.dev/report?url=https%3A%2F%2Falshedivat.github.io%2Fal-folio%2F&form_factor=desktop)
+
+## Table Of Contents
+
+- [al-folio](#al-folio)
+ - [User community](#user-community)
+ - [Lighthouse PageSpeed Insights](#lighthouse-pagespeed-insights)
+ - [Table Of Contents](#table-of-contents)
+ - [Getting started](#getting-started)
+ - [Installation](#installation)
+ - [Local setup using Docker (Recommended on Windows)](#local-setup-using-docker-recommended-on-windows)
+ - [Local Setup (Standard)](#local-setup-standard)
+ - [Deployment](#deployment)
+ - [Upgrading from a previous version](#upgrading-from-a-previous-version)
+ - [FAQ](#faq)
+ - [Features](#features)
+ - [Publications](#publications)
+ - [Collections](#collections)
+ - [Layouts](#layouts)
+ - [The iconic style of Distill](#the-iconic-style-of-distill)
+ - [Full support for math \& code](#full-support-for-math--code)
+ - [Photos](#photos)
+ - [Other features](#other-features)
+ - [GitHub's repositories and user stats](#githubs-repositories-and-user-stats)
+ - [Theming](#theming)
+ - [Social media previews](#social-media-previews)
+ - [Atom (RSS-like) Feed](#atom-rss-like-feed)
+ - [Related posts](#related-posts)
+ - [Contributing](#contributing)
+ - [Maintainers](#maintainers)
+ - [License](#license)
+
+## Getting started
+
+Want to learn more about Jekyll? Check out [this tutorial](https://www.taniarascia.com/make-a-static-website-with-jekyll/).
+Why Jekyll? Read [Andrej Karpathy's blog post](https://karpathy.github.io/2014/07/01/switching-to-jekyll/)!
+
+### Installation
+
+For a hands-on walkthrough of al-folio installation, check out [this cool video tutorial](https://www.youtube.com/watch?v=g6AJ9qPPoyc) by one of the community members! 🎬 🍿
+
+The preferred way of using this template is by clicking in [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template#creating-a-repository-from-a-template) above the file list.
+Then, create a new repository at `github.com:/`. If you plan to upload your site to `.github.io`,
+note that the name of your repository must be `.github.io` or `.github.io`, as stated in the [GitHub pages docs](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites).
+For more information on how to deploy your site, check the [Deployment](#deployment) section below. After you created your new repository, just download it to your machine:
+
+```bash
+$ git clone git@github.com:/.git
+$ cd
+```
+
+---
+
+#### Local setup using Docker (Recommended on Windows)
+
+You need to take the following steps to get `al-folio` up and running in your local machine:
+
+- First, install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/).
+- Finally, run the following command that will pull a pre-built image from DockerHub and will run your website.
+
+```bash
+$ docker-compose up
+```
+
+Note that when you run it for the first time, it will download a docker image of size 300MB or so.
+
+Now, feel free to customize the theme however you like (don't forget to change the name!). After you are done, you can use the same command (`docker-compose up`) to render the webpage with all you changes. Also, make sure to commit your final changes.
+
+> To change port number, you can edit `docker-compose.yml` file.
+
+(click to expand) Build your own docker image:
+
+> Note: this approach is only necessary if you would like to build an older or very custom version of al-folio.
+
+Build and run a new docker image using:
+
+```bash
+$ docker-compose -f docker-local.yml up
+```
+
+> If you want to update jekyll, install new ruby packages, etc., all you have to do is build the image again using `--force-recreate` argument at the end of previous command! It will download ruby and jekyll and install all ruby packages again from scratch.
+
+
+
+---
+
+#### Local Setup (Standard)
+
+Assuming you have [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed on your system (*hint: for ease of managing ruby gems, consider using [rbenv](https://github.com/rbenv/rbenv)*).
+
+```bash
+$ bundle install
+$ bundle exec jekyll serve --lsi
+```
+
+Now, feel free to customize the theme however you like (don't forget to change the name!).
+After you are done, **commit** your final changes.
+
+---
+
+#### Deployment
+
+Deploying your website to [GitHub Pages](https://pages.github.com/) is the most popular option.
+Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository! :sparkles:
+
+**For personal and organization webpages:**
+
+1. The name of your repository **MUST BE** `.github.io` or `.github.io`.
+2. In `_config.yml`, set `url` to `https://.github.io` and leave `baseurl` empty.
+3. Set up automatic deployment of your webpage (see instructions below).
+4. Make changes, commit, and push!
+5. After deployment, the webpage will become available at `.github.io`.
+
+**For project pages:**
+
+1. In `_config.yml`, set `url` to `https://.github.io` and `baseurl` to `//`.
+2. Set up automatic deployment of your webpage (see instructions below).
+3. Make changes, commit, and push!
+4. After deployment, the webpage will become available at `.github.io//`.
+
+**To enable automatic deployment:**
+
+1. Click on **Actions** tab and **Enable GitHub Actions**; do not worry about creating any workflows as everything has already been set for you.
+2. Go to Settings -> Actions -> General -> Workflow permissions, and give **Read and write permissions** to GitHub Actions
+3. Make any other changes to your webpage, commit, and push. This will automatically trigger the **Deploy** action.
+4. Wait for a few minutes and let the action complete. You can see the progress in the **Actions** tab. If completed successfully, in addition to the `master` branch, your repository should now have a newly built `gh-pages` branch.
+5. Finally, in the **Settings** of your repository, in the Pages section, set the branch to `gh-pages` (**NOT** to `master`). For more details, see [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source).
+
+If you keep your site on another branch, open `.github/workflows/deploy.yml` **on the branch you keep your website on** and change on->push->branches and on->pull\_request->branches to the branch you keep your website on. This will trigger the action on pulls/pushes on that branch. The action will then deploy the website on the branch it was triggered from.
+
+(click to expand) Manual deployment to GitHub Pages:
+
+If you need to manually re-deploy your website to GitHub pages, go to Actions, click "Deploy" in the left sidebar, then "Run workflow."
+
+
+
+(click to expand) Deployment to another hosting server (non GitHub Pages):
+
+If you decide to not use GitHub Pages and host your page elsewhere, simply run:
+
+```bash
+$ bundle exec jekyll build --lsi
+```
+
+which will (re-)generate the static webpage in the `_site/` folder.
+Then simply copy the contents of the `_site/` directory to your hosting server.
+
+**Note:** Make sure to correctly set the `url` and `baseurl` fields in `_config.yml` before building the webpage. If you are deploying your webpage to `your-domain.com/your-project/`, you must set `url: your-domain.com` and `baseurl: /your-project/`. If you are deploying directly to `your-domain.com`, leave `baseurl` blank.
+
+
+
+(click to expand) Deployment to a separate repository (advanced users only):
+
+**Note:** Do not try using this method unless you know what you are doing (make sure you are familiar with [publishing sources](https://help.github.com/en/github/working-with-github-pages/about-github-pages#publishing-sources-for-github-pages-sites)). This approach allows to have the website's source code in one repository and the deployment version in a different repository.
+
+Let's assume that your website's publishing source is a `publishing-source` subdirectory of a git-versioned repository cloned under `$HOME/repo/`.
+For a user site this could well be something like `$HOME/.github.io`.
+
+Firstly, from the deployment repo dir, checkout the git branch hosting your publishing source.
+
+Then from the website sources dir (commonly your al-folio fork's clone):
+
+```bash
+$ bundle exec jekyll build --lsi --destination $HOME/repo/publishing-source
+```
+
+This will instruct jekyll to deploy the website under `$HOME/repo/publishing-source`.
+
+**Note:** Jekyll will clean `$HOME/repo/publishing-source` before building!
+
+The quote below is taken directly from the [jekyll configuration docs](https://jekyllrb.com/docs/configuration/options/):
+
+> Destination folders are cleaned on site builds
+>
+> The contents of `` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `` configuration directive.
+>
+> Do not use an important location for ``; instead, use it as a staging area and copy files from there to your web server.
+
+If `$HOME/repo/publishing-source` contains files that you want jekyll to leave untouched, specify them under `keep_files` in `_config.yml`.
+In its default configuration, al-folio will copy the top-level `README.md` to the publishing source. If you want to change this behavior, add `README.md` under `exclude` in `_config.yml`.
+
+**Note:** Do _not_ run `jekyll clean` on your publishing source repo as this will result in the entire directory getting deleted, irrespective of the content of `keep_files` in `_config.yml`.
+
+
+
+---
+
+#### Upgrading from a previous version
+
+If you installed **al-folio** as described above, you can configure a [GitHub action](https://github.com/AndreasAugustin/actions-template-sync) to automatically sync your repository with the latest version of the theme.
+
+Go to Settings -> Actions -> General -> Workflow permissions, give Read and write permissions to GitHub Actions, check "Allow GitHub Actions to create and approve pull requests", and save your changes.
+
+Then go to Actions -> New workflow -> set up a workflow yourself, setup the following workflow and commit your changes:
+
+```yaml
+name: Sync from template
+on:
+ # cronjob trigger
+ schedule:
+ - cron: "0 0 1 * *"
+ # manual trigger
+ workflow_dispatch:
+jobs:
+ repo-sync:
+ runs-on: ubuntu-latest
+ steps:
+ # To use this repository's private action, you must check out the repository
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: actions-template-sync
+ uses: AndreasAugustin/actions-template-sync@v0.7.3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ source_repo_path: alshedivat/al-folio
+ upstream_branch: master
+```
+
+You will receive a pull request within your repository if there are some changes available in the template.
+
+Another option is to manually update your code by following the steps below:
+
+```bash
+# Assuming the current directory is
+$ git remote add upstream https://github.com/alshedivat/al-folio.git
+$ git fetch upstream
+$ git rebase v0.9.0
+```
+
+If you have extensively customized a previous version, it might be trickier to upgrade.
+You can still follow the steps above, but `git rebase` may result in merge conflicts that must be resolved.
+See [git rebase manual](https://help.github.com/en/github/using-git/about-git-rebase) and how to [resolve conflicts](https://help.github.com/en/github/using-git/resolving-merge-conflicts-after-a-git-rebase) for more information.
+If rebasing is too complicated, we recommend re-installing the new version of the theme from scratch and port over your content and changes from the previous version manually.
+
+---
+
+### FAQ
+
+Here are some frequently asked questions.
+If you have a different question, please ask using [Discussions](https://github.com/alshedivat/al-folio/discussions/categories/q-a).
+
+1. **Q:** After I create a new repository from this template and setup the repo, I get a deployment error.
+ Isn't the website supposed to correctly deploy automatically?
+ **A:** Yes, if you are using release `v0.3.5` or later, the website will automatically and correctly re-deploy right after your first commit.
+ Please make some changes (e.g., change your website info in `_config.yml`), commit, and push.
+ Make sure to follow [deployment instructions](https://github.com/alshedivat/al-folio#deployment) in the previous section.
+ (Relevant issue: [209](https://github.com/alshedivat/al-folio/issues/209#issuecomment-798849211).)
+
+2. **Q:** I am using a custom domain (e.g., `foo.com`).
+ My custom domain becomes blank in the repository settings after each deployment.
+ How do I fix that?
+ **A:** You need to add `CNAME` file to the `master` or `source` branch of your repository.
+ The file should contain your custom domain name.
+ (Relevant issue: [130](https://github.com/alshedivat/al-folio/issues/130).)
+
+3. **Q:** My webpage works locally.
+ But after deploying, it is not displayed correctly (CSS and JS is not loaded properly).
+ How do I fix that?
+ **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`.
+ Set `url` to `https://.github.io` or to `https://` if you are using a custom domain.
+ If you are deploying a personal or organization website, leave `baseurl` blank.
+ If you are deploying a project page, set `baseurl: //`.
+
+4. **Q:** Atom feed doesn't work. Why?
+
+ **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`.
+ RSS Feed plugin works with these correctly set up fields: `title`, `url`, `description` and `author`.
+ Make sure to fill them in an appropriate way and try again.
+
+5. **Q:** My site doesn't work when I enable `related_blog_posts`. Why?
+ **A:** This is probably due to the [classifier reborn](https://github.com/jekyll/classifier-reborn) plugin, which is used to calculate
+ related posts. If the error states `Liquid Exception: Zero vectors can not be normalized...`, it means that it could not calculate related
+ posts for a specific post. This is usually caused by [empty or minimal blog posts](https://github.com/jekyll/classifier-reborn/issues/64)
+ without meaningful words (i.e. only [stop words](https://en.wikipedia.org/wiki/Stop_words)) or even
+ [specific characters](https://github.com/jekyll/classifier-reborn/issues/194) you used in your posts. Also, the calculus for similar posts are
+ made for every `post`, which means every page that uses `layout: post`, including the announcements. To change this behavior, simply add
+ `related_posts: false` to the front matter of the page you don't want to display related posts on.
+
+## Features
+
+### Publications
+
+Your publications' page is generated automatically from your BibTex bibliography.
+Simply edit `_bibliography/papers.bib`.
+You can also add new `*.bib` files and customize the look of your publications however you like by editing `_pages/publications.md`.
+
+
+
+(click to expand) Author annotation:
+
+In publications, the author entry for yourself is identified by string array `scholar:last_name` and string array `scholar:first_name` in `_config.yml`:
+
+```yaml
+scholar:
+ last_name: [Einstein]
+ first_name: [Albert, A.]
+```
+
+If the entry matches one form of the last names and the first names, it will be underlined.
+Keep meta-information about your co-authors in `_data/coauthors.yml` and Jekyll will insert links to their webpages automatically.
+The co-author data format in `_data/coauthors.yml` is as follows,
+
+```yaml
+"Adams":
+ - firstname: ["Edwin", "E.", "E. P.", "Edwin Plimpton"]
+ url: https://en.wikipedia.org/wiki/Edwin_Plimpton_Adams
+
+"Podolsky":
+ - firstname: ["Boris", "B.", "B. Y.", "Boris Yakovlevich"]
+ url: https://en.wikipedia.org/wiki/Boris_Podolsky
+
+"Rosen":
+ - firstname: ["Nathan", "N."]
+ url: https://en.wikipedia.org/wiki/Nathan_Rosen
+
+"Bach":
+ - firstname: ["Johann Sebastian", "J. S."]
+ url: https://en.wikipedia.org/wiki/Johann_Sebastian_Bach
+
+ - firstname: ["Carl Philipp Emanuel", "C. P. E."]
+ url: https://en.wikipedia.org/wiki/Carl_Philipp_Emanuel_Bach
+```
+
+If the entry matches one of the combinations of the last names and the first names, it will be highlighted and linked to the url provided.
+
+
+
+(click to expand) Buttons (through custom bibtex keywords):
+
+There are several custom bibtex keywords that you can use to affect how the entries are displayed on the webpage:
+
+- `abbr`: Adds an abbreviation to the left of the entry. You can add links to these by creating a venue.yaml-file in the _data folder and adding entries that match.
+- `abstract`: Adds an "Abs" button that expands a hidden text field when clicked to show the abstract text
+- `arxiv`: Adds a link to the Arxiv website (Note: only add the arxiv identifier here - the link is generated automatically)
+- `bibtex_show`: Adds a "Bib" button that expands a hidden text field with the full bibliography entry
+- `html`: Inserts an "HTML" button redirecting to the user-specified link
+- `pdf`: Adds a "PDF" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
+- `supp`: Adds a "Supp" button to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
+- `blog`: Adds a "Blog" button redirecting to the specified link
+- `code`: Adds a "Code" button redirecting to the specified link
+- `poster`: Adds a "Poster" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
+- `slides`: Adds a "Slides" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory)
+- `website`: Adds a "Website" button redirecting to the specified link
+- `altmetric`: Adds an [Altmetric](https://www.altmetric.com/) badge (Note: if DOI is provided just use `true`, otherwise only add the altmetric identifier here - the link is generated automatically)
+- `dimensions`: Adds a [Dimensions](https://www.dimensions.ai/) badge (Note: if DOI or PMID is provided just use `true`, otherwise only add the Dimensions' identifier here - the link is generated automatically)
+
+You can implement your own buttons by editing the bib.html file.
+
+
+
+---
+
+### Collections
+
+This Jekyll theme implements `collections` to let you break up your work into categories.
+The theme comes with two default collections: `news` and `projects`.
+Items from the `news` collection are automatically displayed on the home page.
+Items from the `projects` collection are displayed on a responsive grid on projects page.
+
+
+
+You can easily create your own collections, apps, short stories, courses, or whatever your creative work is.
+To do this, edit the collections in the `_config.yml` file, create a corresponding folder, and create a landing page for your collection, similar to `_pages/projects.md`.
+
+---
+
+### Layouts
+
+**al-folio** comes with stylish layouts for pages and blog posts.
+
+#### The iconic style of Distill
+
+The theme allows you to create blog posts in the [distill.pub](https://distill.pub/) style:
+
+
+
+For more details on how to create distill-styled posts using `` tags, please refer to [the example](https://alshedivat.github.io/al-folio/blog/2021/distill/).
+
+#### Full support for math & code
+
+**al-folio** supports fast math typesetting through [MathJax](https://www.mathjax.org/) and code syntax highlighting using [GitHub style](https://github.com/jwarby/jekyll-pygments-themes):
+
+
+
+
+
+
+#### Photos
+
+Photo formatting is made simple using [Bootstrap's grid system](https://getbootstrap.com/docs/4.4/layout/grid/).
+Easily create beautiful grids within your blog posts and project pages:
+
+
+
+---
+
+### Other features
+
+#### GitHub's repositories and user stats
+
+**al-folio** uses [github-readme-stats](https://github.com/anuraghazra/github-readme-stats) and [github-profile-trophy](https://github.com/ryo-ma/github-profile-trophy)
+to display GitHub repositories and user stats on the `/repositories/` page.
+
+Edit the `_data/repositories.yml` and change the `github_users` and `github_repos` lists to include your own GitHub profile and repositories to the `/repositories/` page.
+
+You may also use the following codes for displaying this in any other pages.
+
+```html
+
+{% if site.data.repositories.github_users %}
+
+ {% for user in site.data.repositories.github_users %}
+ {% include repository/repo_user.html username=user %}
+ {% endfor %}
+
+{% endif %}
+
+
+{% if site.repo_trophies.enabled %}
+{% for user in site.data.repositories.github_users %}
+ {% if site.data.repositories.github_users.size > 1 %}
+
{{ user }}
+ {% endif %}
+
+ {% include repository/repo_trophies.html username=user %}
+
+ {% for repo in site.data.repositories.github_repos %}
+ {% include repository/repo.html repository=repo %}
+ {% endfor %}
+
+{% endif %}
+```
+
+#### Theming
+
+A variety of beautiful theme colors have been selected for you to choose from.
+The default is purple, but you can quickly change it by editing the
+`--global-theme-color` variable in the `_sass/_themes.scss` file.
+Other color variables are listed there as well.
+The stock theme color options available can be found at `_sass/variables.scss`.
+You can also add your own colors to this file assigning each a name for ease of
+use across the template.
+
+#### Social media previews
+
+**al-folio** supports preview images on social media.
+To enable this functionality you will need to set `serve_og_meta` to `true` in your `_config.yml`.
+Once you have done so, all your site's pages will include Open Graph data in the HTML head element.
+
+You will then need to configure what image to display in your site's social media previews.
+This can be configured on a per-page basis, by setting the `og_image` page variable.
+If for an individual page this variable is not set, then the theme will fall back to a site-wide `og_image` variable, configurable in your `_config.yml`.
+In both the page-specific and site-wide cases, the `og_image` variable needs to hold the URL for the image you wish to display in social media previews.
+
+#### Atom (RSS-like) Feed
+
+It generates an Atom (RSS-like) feed of your posts, useful for Atom and RSS readers.
+The feed is reachable simply by typing after your homepage `/feed.xml`.
+E.g. assuming your website mountpoint is the main folder, you can type `yourusername.github.io/feed.xml`
+
+#### Related posts
+
+By default, there will be a related posts section on the bottom of the blog posts.
+These are generated by selecting the `max_related` most recent posts that share at least `min_common_tags` tags with the current post.
+If you do not want to display related posts on a specific post, simply add `related_posts: false` to the front matter of the post.
+If you want to disable it for all posts, simply set `enabled` to false in the `related_blog_posts` section in `_config.yml`.
+
+## Contributing
+
+Contributions to al-folio are very welcome!
+Before you get started, please take a look at [the guidelines](CONTRIBUTING.md).
+
+If you would like to improve documentation, add your webpage to the list below, or fix a minor inconsistency or bug, please feel free to send a PR directly to `master`.
+For more complex issues/bugs or feature requests, please open an issue using the appropriate template.
+
+### Maintainers
+
+Our most active contributors are welcome to join the maintainers team.
+If you are interested, please reach out!
+
+
+
+
+
+ LightAD examines model choice, preprocessing, and efficiency in log anomaly detection.
+
+
+
+ Connected research themes, with links to individual works. The grouping describes shared
+ questions rather than a chronological sequence.
+
+
+
+
diff --git a/src/components/TestLab.astro b/src/components/TestLab.astro
new file mode 100644
index 0000000000000..71dd124cb331c
--- /dev/null
+++ b/src/components/TestLab.astro
@@ -0,0 +1,198 @@
+---
+interface Props {
+ compact?: boolean;
+}
+const { compact = false } = Astro.props;
+---
+
+
+
+ A small test of confidencePython
+
+
+ # Return the largest number {'def '}
+ largest(numbers): best = 0 for n in numbers: best = max(best, n) return best
+
+
+
+ Test inputExpectedResult
+
+
[2, 7, 4]7Pass
+
[0, 3, 1]3Pass
+
+ [-8, -2, -5]-2Fail: 0
+
+
+
+ 2 / 2 passed
+
+
+ All tests pass. Is the function correct?
+
+
+
+
+
+
+
diff --git a/src/content.config.ts b/src/content.config.ts
new file mode 100644
index 0000000000000..03da2c04cdc3c
--- /dev/null
+++ b/src/content.config.ts
@@ -0,0 +1,27 @@
+import { defineCollection } from 'astro:content';
+import { z } from 'astro/zod';
+import { glob } from 'astro/loaders';
+
+const writing = defineCollection({
+ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/writing' }),
+ schema: z
+ .object({
+ title: z.string(),
+ description: z.string(),
+ publishedAt: z.coerce.date(),
+ updatedAt: z.coerce.date().optional(),
+ language: z.enum(['en', 'zh-CN']).default('en'),
+ topics: z.array(z.string()).min(1),
+ audience: z.string(),
+ draft: z.boolean().default(true),
+ featured: z.boolean().default(false),
+ series: z.string().optional(),
+ order: z.number().int().positive().optional(),
+ translationOf: z.string().optional(),
+ })
+ .refine((data) => Boolean(data.series) === Boolean(data.order), {
+ message: 'A series and its order must be supplied together.',
+ }),
+});
+
+export const collections = { writing };
diff --git a/src/content/writing/passing-tests-is-not-correctness.md b/src/content/writing/passing-tests-is-not-correctness.md
new file mode 100644
index 0000000000000..cdd7e3aeb75ed
--- /dev/null
+++ b/src/content/writing/passing-tests-is-not-correctness.md
@@ -0,0 +1,98 @@
+---
+title: 'Passing tests is not the same as being correct'
+description: 'A small function reveals a useful distinction between evidence, coverage, and correctness in AI-assisted programming.'
+publishedAt: 2026-09-08
+language: en
+topics: [Software testing, Coding agents]
+audience: developers and technical students
+draft: true
+featured: true
+series: Evaluating AI in practice
+order: 1
+---
+
+A coding agent produces a patch. The tests pass. Is the task solved?
+
+The answer depends on what the tests establish. A green result means that the program met the assertions in the cases that actually ran, under the conditions of that run. It does not automatically mean that the program satisfies the intended specification.
+
+This distinction is easier to see in a very small program.
+
+## A bug hiding in plain sight
+
+Suppose the contract is to return the largest integer in a non-empty list of integers:
+
+```python
+def largest(numbers):
+ best = 0
+ for n in numbers:
+ best = max(best, n)
+ return best
+```
+
+Both of these checks pass:
+
+```python
+assert largest([2, 7, 4]) == 7
+assert largest([0, 3, 1]) == 3
+```
+
+Yet the function is incorrect. On `[-8, -2, -5]`, it returns `0`. The expected answer is `-2`. The initial value silently assumed that the answer would never be negative.
+
+You can [step through this example](/education/) before reading on.
+
+## What the green result actually told us
+
+The two checks provide evidence about two inputs. Both exercise a similar assumption: at least one input is non-negative. Adding many more positive-only cases could preserve that blind spot.
+
+The issue is not simply the number of tests. It is whether the inputs and assertions distinguish a correct implementation from plausible incorrect ones.
+
+Code coverage is useful, but it answers a different question. Executing the return statement, or even every line in this function, does not establish that the initial value was appropriate for every input class.
+
+## Start with the contract
+
+A better workflow begins with a question: what must be true of the result?
+
+For this function, given a non-empty list of integers:
+
+- The result must be an element of the input.
+- No input element may be greater than the result.
+
+Those properties immediately make the negative-only case interesting. They also suggest cases involving a single element, repeated maxima, and zero. Empty input is outside this contract; the interface should reject it or specify a separate behavior.
+
+One implementation is:
+
+```python
+def largest(numbers):
+ if not numbers:
+ raise ValueError("expected a non-empty list")
+ best = numbers[0]
+ for n in numbers[1:]:
+ best = max(best, n)
+ return best
+```
+
+For the stated integer-list contract, initializing from the first element removes the assumption that caused the bug. This does not define behavior for arbitrary Python objects or floating-point values such as NaN; those require separate decisions.
+
+## Carry the distinction into AI evaluation
+
+When a test suite scores a generated patch, the same distinction matters. A passing patch may implement the intended behavior, or it may happen to satisfy an incomplete set of assertions. The score alone does not tell us which explanation applies.
+
+Useful evaluation questions include:
+
+- Which behaviors are represented by the tests?
+- What plausible incorrect patches could still pass?
+- Are the checks independent of the system producing the answer?
+- Have the tests themselves been checked for errors?
+
+These questions motivate work on more rigorous coding-agent evaluation, including [UTBoost](/publications/#yu2025utboost) and [SWE-ABS](/publications/#yu2026sweabs). The toy example here illustrates the general distinction; it is not an experiment from either paper.
+
+## Try it yourself
+
+Write an incorrect version of `largest` that passes the original two checks in a different way. Then add the smallest test that separates it from the intended implementation.
+
+The exercise changes the question from "Do I have enough tests?" to "Which mistakes can my tests detect?"
+
+## References
+
+- [UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench](https://arxiv.org/abs/2506.09289)
+- [Retromorphic Testing: A New Approach to the Test Oracle Problem](https://arxiv.org/abs/2310.06433)
diff --git a/src/content/writing/reading-a-coding-agent-benchmark.md b/src/content/writing/reading-a-coding-agent-benchmark.md
new file mode 100644
index 0000000000000..c2f327ba91d19
--- /dev/null
+++ b/src/content/writing/reading-a-coding-agent-benchmark.md
@@ -0,0 +1,71 @@
+---
+title: 'Before trusting a benchmark score, inspect the benchmark'
+description: 'A practical reading guide to tasks, tests, execution conditions, and the conclusions a coding-agent result can support.'
+publishedAt: 2026-09-08
+language: en
+topics: [AI evaluation, Coding agents]
+audience: developers and research readers
+draft: true
+featured: true
+series: Evaluating AI in practice
+order: 2
+---
+
+A headline score compresses many choices into one number. For a coding agent, those choices include the task set, available tools, execution budget, test suite, and rule used to count a task as resolved.
+
+The number is useful when we understand what it measures. Here is a practical way to read the evidence behind it.
+
+## Begin with the unit of success
+
+Find the exact condition that marks an individual task as successful. Is it a set of passing tests? A human review? A combination of checks? Does success require avoiding regressions as well as fixing the reported issue?
+
+"Resolved" is an operational definition. It becomes meaningful when the benchmark documents how it is computed.
+
+The [previous article](/writing/passing-tests-is-not-correctness/) explains why test success and correctness are related but different claims.
+
+## Inspect the task distribution
+
+Look at the repositories, languages, task types, and time period represented in the benchmark. A result on a particular set of repository issues does not by itself establish performance on every kind of engineering work.
+
+Ask whether the tasks resemble the work you need the agent to do. A tool that performs well on small bug fixes may need separate evaluation for requirements discovery, security review, or long-running maintenance.
+
+## Read the execution conditions
+
+Two reported scores can be difficult to compare if the systems received different resources.
+
+Record the model version, tool access, context available to the agent, retry policy, time or token budget, and number of attempts. Check whether the result describes one attempt per task or selection among multiple attempts.
+
+These details do not make a result good or bad by themselves. They determine which comparison is justified and what cost accompanies it.
+
+## Examine the tests as measurement instruments
+
+Tests can miss incorrect behavior. Tests can also encode a mistaken expectation or depend on an unstable environment. Stronger evaluation requires checking the tests as well as the generated patches.
+
+Look for evidence of manual inspection, independent test construction, adversarial checks, or an analysis of false positives and false negatives. No one technique guarantees a perfect benchmark. Each can make a different weakness easier to see.
+
+Research such as [UTBoost](/publications/#yu2025utboost) investigates more rigorous evaluation of coding agents on SWE-Bench. Use the paper's actual methodology and scope when interpreting its findings; a title or aggregate score is not a substitute for that detail.
+
+## Keep a comparison record
+
+For the next benchmark result you read, write down:
+
+1. The task set and its version.
+2. The success condition.
+3. The execution environment and resource budget.
+4. The number of attempts and any selection procedure.
+5. Known limitations of the evaluation.
+
+If an item is not reported, record it as unknown. Avoid silently filling the gap with an assumption that makes the comparison easier.
+
+## Bring the question back to your own work
+
+A benchmark can help select candidates for a local evaluation. It cannot replace checking whether an agent handles your repositories, requirements, tools, and failure costs.
+
+Start with a small, representative set of tasks. Inspect both successes and failures. Keep the prompts and evaluation conditions reproducible. Expand the evaluation when you discover a new failure class.
+
+The useful question is specific: what evidence supports using this system for this task, under these conditions?
+
+## References
+
+- [UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench](https://arxiv.org/abs/2506.09289)
+- [How Should We Build A Benchmark? Revisiting 274 Code-Related Benchmarks For LLMs](https://arxiv.org/abs/2501.10711)
diff --git a/src/data/research.ts b/src/data/research.ts
new file mode 100644
index 0000000000000..80009253404b7
--- /dev/null
+++ b/src/data/research.ts
@@ -0,0 +1,35 @@
+export const researchGroups = [
+ {
+ id: 'coding-agents',
+ title: 'Evaluating coding agents',
+ question: 'What does a passing benchmark establish?',
+ description: 'Strengthening tests and examining the reliability of benchmark results.',
+ projects: ['swe-abs', 'utboost'],
+ related: [{ name: 'Benchmark design', href: '/publications/#cao2025' }],
+ },
+ {
+ id: 'test-oracles',
+ title: 'Constructing test oracles',
+ question: 'How can we test without a known answer?',
+ description: 'Using relations between programs and executions to detect inconsistencies.',
+ projects: ['retromorphic-testing'],
+ related: [],
+ },
+ {
+ id: 'ai-systems',
+ title: 'Testing AI systems',
+ question: 'Which changes should an AI system respond to?',
+ description: 'Controlled transformations reveal errors in vision and language systems.',
+ projects: ['rome', 'tin'],
+ related: [{ name: 'MetaIC', href: '/publications/#yu2022automated' }],
+ },
+];
+
+export const empiricalResearch = {
+ id: 'aiops',
+ title: 'AIOps & empirical evaluation',
+ question: 'When is a simpler model enough?',
+ description: 'Studying accuracy, preprocessing, and computational cost in log anomaly detection.',
+ projects: ['lightad'],
+ related: [],
+};
diff --git a/src/data/services.json b/src/data/services.json
new file mode 100644
index 0000000000000..e3b93fd6eebe3
--- /dev/null
+++ b/src/data/services.json
@@ -0,0 +1,47 @@
+[
+ {
+ "year": 2025,
+ "items": [
+ "Shadow Research Track Program Committee – IEEE International Conference on Software Engineering (ICSE 2025)",
+ "Program Committee – IEEE International Conference on Software Analysis, Evolution and Engineering (SANER 2025)"
+ ]
+ },
+ {
+ "year": 2024,
+ "items": [
+ "Artifact Evaluation Committee – 18th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2024)",
+ "Artifact Evaluation Committee – 2024 USENIX Annual Technical Conference (ATC 2024)",
+ "Reviewer – IEEE Transactions on Software Engineering",
+ "Reviewer – ACM Transactions on Software Engineering and Methodology",
+ "Reviewer – Journal of Systems and Software",
+ "External Reviewer – 46th International Conference on Software Engineering (ICSE 2024)",
+ "External Reviewer – ACM International Conference on the Foundations of Software Engineering (FSE 2024)",
+ "Artifact Evaluation Committee – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2024)",
+ "Artifact Evaluation Committee – ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA 2024)"
+ ]
+ },
+ {
+ "year": 2023,
+ "items": [
+ "Artifact Evaluation Committee – 17th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2023)",
+ "Artifact Evaluation Committee – 2023 USENIX Annual Technical Conference (ATC 2023)",
+ "External Reviewer – 32nd ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE 2023)",
+ "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2023)"
+ ]
+ },
+ {
+ "year": 2022,
+ "items": [
+ "Artifact Evaluation Committee – 16th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2022)",
+ "Artifact Evaluation Committee – 2022 USENIX Annual Technical Conference (ATC 2022)",
+ "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2022)",
+ "External Artifact Evaluation Reviewer – 49th ACM SIGPLAN Symposium on Principles of Programming Languages (POPL 2022)"
+ ]
+ },
+ {
+ "year": 2021,
+ "items": [
+ "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2021)"
+ ]
+ }
+]
diff --git a/src/data/site.ts b/src/data/site.ts
new file mode 100644
index 0000000000000..5a48558e0da72
--- /dev/null
+++ b/src/data/site.ts
@@ -0,0 +1,129 @@
+export const site = {
+ name: 'Boxi Yu',
+ url: 'https://boxiyu.github.io',
+ role: 'Senior Research Fellow at Lero, Ireland',
+ email: 'boxi.yu@lero.ie',
+ description:
+ 'Boxi Yu, Senior Research Fellow at Lero, Ireland. Research on software testing, trustworthy AI, and the evaluation of coding agents.',
+ scholar: 'https://scholar.google.com/citations?user=Tat3jMQAAAAJ',
+ github: 'https://github.com/BoxiYu',
+ orcid: 'https://orcid.org/0000-0001-5213-7189',
+};
+
+export const projects = [
+ {
+ id: 'swe-abs',
+ paper: 'yu2026sweabs',
+ name: 'SWE-ABS',
+ year: '2026',
+ venue: 'ICML',
+ question: 'What does a passing benchmark really prove?',
+ summary:
+ 'Coverage- and mutation-driven test augmentation rejected 19.71% of previously passing patches in our evaluation of 30 agents on SWE-Bench Verified.',
+ method:
+ 'SWE-ABS first uses program slicing to guide tests toward untested code, then uses plausible incorrect patches to generate adversarial tests that expose semantic blind spots.',
+ finding:
+ "The study strengthened tests for 50.2% of the 500 benchmark instances. The leading evaluated agent's success rate fell from 78.80% to 62.20%, and the previously top-ranked agent moved to fifth place. These figures describe the systems and benchmark evaluated in the paper.",
+ links: [{ label: 'Paper', href: 'https://arxiv.org/abs/2603.00520' }],
+ topic: 'Coding agent evaluation',
+ },
+ {
+ id: 'utboost',
+ paper: 'yu2025utboost',
+ name: 'UTBoost',
+ year: '2025',
+ venue: 'ACL',
+ question: 'How rigorously do we evaluate coding agents?',
+ summary:
+ 'Generated unit tests exposed 345 erroneous patches that had originally passed SWE-Bench evaluation, showing how test quality changes conclusions about coding agents.',
+ method:
+ 'UTGenerator analyzes project code and dependencies to generate executable unit tests for real Python projects. UTBoost augments the benchmark test suites and re-evaluates agent patches against the stronger tests.',
+ finding:
+ 'The study identified 36 instances with insufficient tests and 345 erroneous patches previously classified as passing. Re-evaluation changed 18 leaderboard positions on SWE-Bench Lite and 11 on Verified in the studied submissions.',
+ links: [
+ { label: 'ACL paper', href: 'https://aclanthology.org/2025.acl-long.189/' },
+ { label: 'Code & test artifacts', href: 'https://github.com/CUHK-Shenzhen-SE/UTBoost' },
+ {
+ label: 'Verified dataset',
+ href: 'https://huggingface.co/datasets/Bertsekas/SWE-Bench_Verified_UTBoost',
+ },
+ ],
+ topic: 'Benchmark reliability',
+ },
+ {
+ id: 'retromorphic-testing',
+ paper: 'yu2023Retro',
+ name: 'Retromorphic Testing',
+ year: '2023',
+ venue: 'arXiv',
+ question: 'How do we test without a known answer?',
+ summary:
+ 'A dual-program approach to constructing test oracles: transform an input, map the output back to the input domain, and check the resulting relation.',
+ method:
+ 'Inspired by inverse functions, a forward program and a backward program connect inputs and outputs. An auxiliary program can serve either role, allowing a relation between the original and transformed inputs to reveal inconsistencies.',
+ finding:
+ 'The paper develops three testing modes and illustrates applications to algorithms, traditional software, and AI systems. The relation depends on the programs and task; it does not require every pair of programs to be exact inverses.',
+ links: [
+ { label: 'Preprint', href: 'https://arxiv.org/abs/2310.06433' },
+ { label: 'Code', href: 'https://github.com/CUHK-Shenzhen-SE/RetromorphicTesting' },
+ ],
+ topic: 'Automated testing',
+ },
+ {
+ id: 'rome',
+ paper: 'yu2023rome',
+ name: 'ROME',
+ year: '2023',
+ venue: 'ISSTA',
+ question: 'Can controlled image changes reveal captioning errors?',
+ summary:
+ 'Object removal and inpainting create natural-looking image pairs for testing the consistency of image captions.',
+ method:
+ 'ROME recursively removes and inpaints objects in an image, then compares the objects mentioned in captions before and after the transformation. This turns expected changes in image content into a metamorphic test oracle.',
+ finding:
+ 'Across one commercial captioning API and four algorithms, the study reported 9,121 erroneous issues from 226 seed images, with precision ranging from 86.47% to 92.17%.',
+ topic: 'Trustworthy AI',
+ links: [
+ { label: 'Paper', href: 'https://arxiv.org/abs/2306.02228' },
+ { label: 'Code', href: 'https://github.com/RobustNLP/TestIC' },
+ ],
+ },
+ {
+ id: 'tin',
+ paper: 'yu2023tin',
+ name: 'TIN',
+ year: '2023',
+ venue: 'ESEC/FSE',
+ question: 'Can consistency checks both detect and repair NER errors?',
+ summary:
+ 'Metamorphic relations across similar contexts and entities support automated testing and improvement of named entity recognition systems.',
+ method:
+ 'TIN compares entity predictions across related contexts and entities, using inconsistencies to report errors and guide automatic repairs.',
+ finding:
+ 'In the evaluation of two models and the Azure and AWS APIs, 702 of 784 manually inspected reports were confirmed as errors. Automatic repair reduced errors by 26.8% to 50.6% across the evaluated systems.',
+ topic: 'Trustworthy AI',
+ links: [
+ { label: 'Paper', href: 'https://arxiv.org/abs/2308.07937' },
+ { label: 'Code', href: 'https://github.com/RobustNLP/TestNER' },
+ ],
+ },
+ {
+ id: 'lightad',
+ paper: 'yu2024LightAD',
+ name: 'LightAD',
+ year: '2024',
+ venue: 'ICSE',
+ question: 'When is a simpler model enough for log anomaly detection?',
+ summary:
+ 'An empirical comparison of classical and deep learning approaches examines accuracy and computational cost across five log datasets.',
+ method:
+ 'The study compares methods on HDFS, BGL, Spirit, Liberty, and Thunderbird. The accompanying LightAD toolkit combines preprocessing, deduplication, and automated model selection.',
+ finding:
+ 'LightAD makes the trade-off between F1, training time, and inference time explicit in model selection. The comparison motivates evaluating classical baselines and preprocessing choices alongside deep learning models for log-based anomaly detection.',
+ topic: 'AIOps',
+ links: [
+ { label: 'Paper', href: '/assets/pdf/LightAD.pdf' },
+ { label: 'Code', href: 'https://github.com/BoxiYu/LightAD' },
+ ],
+ },
+];
diff --git a/src/env.d.ts b/src/env.d.ts
new file mode 100644
index 0000000000000..a3c4e9ee490b0
--- /dev/null
+++ b/src/env.d.ts
@@ -0,0 +1,10 @@
+///
+declare module 'bibtex-parse-js' {
+ export interface BibEntry {
+ citationKey: string;
+ entryType: string;
+ entryTags: Record;
+ }
+ export function toJSON(input: string): BibEntry[];
+ export function toBibtex(input: BibEntry[]): string;
+}
diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro
new file mode 100644
index 0000000000000..6fabc586af084
--- /dev/null
+++ b/src/layouts/Base.astro
@@ -0,0 +1,104 @@
+---
+import '@fontsource/source-sans-3/latin-400.css';
+import '@fontsource/source-sans-3/latin-500.css';
+import '@fontsource/source-sans-3/latin-600.css';
+import '@fontsource/source-serif-4/latin-400.css';
+import '@fontsource/source-serif-4/latin-400-italic.css';
+import '../styles/global.css';
+import { site } from '../data/site';
+import { previewDrafts } from '../lib/writing';
+interface Props {
+ title?: string;
+ description?: string;
+ language?: string;
+ noindex?: boolean;
+ article?: boolean;
+}
+const {
+ title,
+ description = site.description,
+ language = 'en',
+ noindex = false,
+ article = false,
+} = Astro.props;
+const path = Astro.url.pathname === '/404/' ? '/404.html' : Astro.url.pathname;
+const canonical = new URL(path, site.url);
+const navigation = [
+ ['Research', '/research/'],
+ ['Publications', '/publications/'],
+ ['Service', '/services/'],
+ ['About', '/about/'],
+];
+const fullTitle = title ? `${title} | Boxi Yu` : 'Boxi Yu | Software Testing & Trustworthy AI';
+---
+
+
+
+
+
+
+
+ {fullTitle}
+
+ {(noindex || previewDrafts) && }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Skip to content
+ {
+ previewDrafts && (
+
+ Local editorial preview. Draft articles are excluded from the published site.
+
+ My research focuses on trustworthy AI, code agents, and automated testing. I proposed
+ Retromorphic Testing, a technique for automatically constructing test oracles for modern
+ software. My work has appeared at ICML, ICSE, ISSTA, ESEC/FSE, and ACL.
+
+ My recent work on UTBoost and SWE-ABS investigates how weaknesses in benchmark tests can
+ inflate the measured success of coding agents. Earlier work develops automated testing
+ methods for image captioning and named entity recognition, and examines the trade-offs
+ between classical and deep learning models for log anomaly detection.
+
+
+
+
+
+
diff --git a/src/pages/education.astro b/src/pages/education.astro
new file mode 100644
index 0000000000000..3c362b2ad539e
--- /dev/null
+++ b/src/pages/education.astro
@@ -0,0 +1,117 @@
+---
+import Base from '../layouts/Base.astro';
+import TestLab from '../components/TestLab.astro';
+import ArticleCard from '../components/ArticleCard.astro';
+import { getWriting } from '../lib/writing';
+const entries = (await getWriting())
+ .filter((entry) => entry.data.series === 'Evaluating AI in practice')
+ .sort((a, b) => (a.data.order || 0) - (b.data.order || 0));
+---
+
+
+
+
+
Build understanding. Then put it to the test.
+ AI education for technical readers. Connecting research ideas to examples you can inspect,
+ question, and use in engineering practice.
+
+
+
+
+ Start with an experiment
+ A passing test suite. An incorrect function.
+
+
+ This Python function is meant to return the largest value in a non-empty list of
+ integers. Two tests pass. Before adding a third, predict an input that could expose a
+ bug.
+
+ You will practice: identifying an untested input class and distinguishing
+ test success from a correctness claim.
+
+ Prerequisite: basic Python. This is a deterministic teaching example, not a live AI
+ model or a reproduction of a research benchmark.
+
+
+
+
+
+
+
What changed when the test changed?
+
+
+ State the contract.
+ The answer must be an element of the non-empty input list and must be at least as
+ large as every other element.
+
+
+ Challenge the assumption.
+ Initializing the result to zero works on these positive examples. It fails when every
+ input is negative.
+
+
+ Improve the implementation and the tests.
+ Initialize from the first element, then test negative values, duplicates, zero, and
+ single-element lists. Define empty-input behavior explicitly.
+
+
+ Keep the conclusion proportional.
+ Broader tests provide stronger evidence. They do not establish that every possible
+ behavior of a complex AI system is correct.
+
+
+
+ See a corrected implementation
{`def largest(numbers):
+ if not numbers:
+ raise ValueError("expected a non-empty list")
+ best = numbers[0]
+ for n in numbers[1:]:
+ best = max(best, n)
+ return best`}
+ This contract is for lists of integers. Other input types need their own specification.
+
+ The same question becomes more consequential when tests are used to score coding agents.
+ UTBoost studies rigorous evaluation on SWE-Bench; SWE-ABS examines inflated success rates
+ on test-based benchmarks.
+
+ No matching publications. Try another title, author, or topic.
+
+
+
+
+
diff --git a/src/pages/research.astro b/src/pages/research.astro
new file mode 100644
index 0000000000000..f2664e332653c
--- /dev/null
+++ b/src/pages/research.astro
@@ -0,0 +1,141 @@
+---
+import Base from '../layouts/Base.astro';
+import { projects, site } from '../data/site';
+const themes = [
+ {
+ id: 'coding-agents',
+ title: 'Evaluating coding agents',
+ description:
+ "A patch can pass a benchmark's tests and still be wrong. I investigate how test adequacy affects measured agent performance, and how to make the evaluation harder to satisfy with incorrect behavior.",
+ projects: ['swe-abs', 'utboost'],
+ },
+ {
+ id: 'test-oracles',
+ title: 'Constructing test oracles',
+ description:
+ 'For many programs, specifying the right answer is harder than running the program. My work explores relations between executions and between programs as a way to detect failures without enumerating correct outputs.',
+ projects: ['retromorphic-testing'],
+ },
+ {
+ id: 'ai-systems',
+ title: 'Testing AI systems',
+ description:
+ 'AI systems produce outputs that can be difficult to assess automatically. Controlled transformations and consistency relations provide practical ways to uncover mistakes in language and vision systems.',
+ projects: ['rome', 'tin'],
+ },
+ {
+ id: 'aiops',
+ title: 'Empirical evaluation for AIOps',
+ description:
+ 'Reliable operational tools need evidence about accuracy, efficiency, and the impact of data preprocessing. I study these choices in log-based anomaly detection.',
+ projects: ['lightad'],
+ },
+];
+---
+
+
+
+
+
Research
+ I develop testing and evaluation methods that uncover failures in software and AI, and
+ examine what our tests actually establish.
+