Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
55 changes: 55 additions & 0 deletions .agents/skills/publication-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
name: publication-review
description: Find, vet, record, and publish Behavioral Data Science Lab paper candidates through the repository's recurring OpenAlex and human-review workflow. Use for publication scans, weekly paper review, include/exclude decisions, duplicate reconciliation, or preparing the publication review pull request.
---

# Publication review

Apply the user's instructions first. Keep discovery, editorial judgment, and publication as separate stages so a source record never becomes site content without a recorded human decision.

## Establish the current state

Read these repository files before deciding anything:

- `maintenance/publication-policy.json` for enforceable thresholds.
- `docs/PUBLICATION_POLICY.md` for the interpretation of membership, identity, and version rules.
- `maintenance/authors.json` and `content/people.json` for verified identities and membership intervals.
- `maintenance/recent-review.md` for the concise current batch; consult `maintenance/review.json` for complete provenance and prior decisions.

Run `python3 scripts/publication_pipeline.py status` and report the counts before collecting or editing.

## Collect

When the user asks for a new scan, run `python3 scripts/publication_pipeline.py collect`. Treat OpenAlex as candidate discovery, not ground truth. The command must leave `content/publications.json` unchanged. If the provider fails or returns a partial result, preserve the previous queue and report the failure.

Use Google Scholar as a coverage cross-check when requested or when recent expected work is missing. Verify a candidate with a primary paper, proceedings, publisher, DOI, or arXiv page. Add source-only gaps to `maintenance/scholar-supplement.json`; never invent an OpenAlex ID.

Supplement entries can have incomplete provider metadata and are not accepted by the OpenAlex decision command. Vet them with the same rule, then use the documented manual content workflow and record the decision in the supplement.

## Vet each candidate

Apply all of these checks:

1. Confirm the full author list from primary evidence. Do not infer identity from a name or initial.
2. Require Tim as an author plus at least one other distinct verified lab author. Tim alone is insufficient, and papers without Tim are ineligible even if they contain multiple lab members. Evaluate past members against membership at the publication date.
3. Treat `needs-membership-review`, `identityReviewPersonIds`, missing dates, and mixed provider profiles as unresolved. Resolve them with evidence or keep the candidate pending.
4. Compare DOI, arXiv ID, normalized title, complete author list, and existing site records. Prefer the final published version while retaining all source observations. Do not collapse datasets, responses, corrections, or errata solely by title.
5. Review venue, year, publication state, ordered authors, URL, and whether the work belongs to the lab. Include qualifying preprints with both `status` and `type` set to `preprint` so the site labels them; prefer a final published version when one exists and do not create both versions.

Map reviewer language as follows: include → `accept`, exclude → `reject`, unsure → leave pending or `defer` to an explicit future date. Rejections and deferrals stay in the durable queue.

Record an OpenAlex decision with `python3 scripts/publication_pipeline.py decide CANDIDATE DECISION`. Acceptance requires repeated `--person PERSON_ID` arguments, including Tim's person ID. If membership or identity remains unresolved but the user explicitly approves an evidence-backed exception, also supply a concise `--reason` and one or more `--evidence URL` arguments. The pipeline stores that audit record and rejects undocumented overrides. An exception cannot waive the requirement that Tim be an author.

## Validate and present

Run `python3 scripts/publication_pipeline.py check` after decisions. Inspect the diff and summarize included, excluded, deferred, unresolved, and duplicate/version outcomes. Never describe a pending candidate as published.

## Push a reviewed batch

Pushing changes and opening a pull request are external mutations. Do this only when the user explicitly asks to push or open the review PR. Use the dedicated `codex/weekly-publication-review` branch and run:

```sh
python3 scripts/publication_pipeline.py publish --base BASE_BRANCH --confirm-push
```

The command must refuse unrelated working-tree or staged changes, run the full check, commit only review artifacts and approved publications, push the dedicated branch, and create or update one draft PR. It must never merge the PR or deploy the site.
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/award.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Award or news
description: Submit an award or lab update with a source
title: "[News] "
body:
- type: input
id: title
attributes:
label: Exact award name or update
validations:
required: true
- type: input
id: recipients
attributes:
label: Recipients or related lab members
validations:
required: true
- type: input
id: date
attributes:
label: Date
placeholder: YYYY-MM-DD
validations:
required: true
- type: input
id: source
attributes:
label: Source URL
validations:
required: true
- type: textarea
id: details
attributes:
label: Awarding organization, linked paper, and details
description: Public information only. New wording requires editorial review.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/profile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Profile or site correction
description: Correct a profile, role, link, opportunity, or site detail
title: "[Correction] "
body:
- type: input
id: page
attributes:
label: Page or person
validations:
required: true
- type: textarea
id: change
attributes:
label: Requested change and source
description: Include the current value and proposed correction. Public information only.
validations:
required: true
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/publication.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publication
description: Submit a paper or a bibliographic correction for review
title: "[Publication] "
body:
- type: input
id: source
attributes:
label: DOI or paper URL
validations:
required: true
- type: input
id: people
attributes:
label: Lab authors
validations:
required: true
- type: dropdown
id: status
attributes:
label: Publication state
options:
- Preprint
- Accepted
- Published
- Correction to existing entry
validations:
required: true
- type: textarea
id: links
attributes:
label: Code, dataset, project links, or correction
description: Public information only. Submissions are reviewed before publication.
9 changes: 9 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Describe the problem and resulting change.

- [ ] Content sources and lab attribution reviewed, if applicable
- [ ] No new prose without approval
- [ ] `npm run check` passes
- [ ] Preview reviewed for affected pages
- [ ] Stable URLs, manual corrections, and review decisions preserved

Deployment is a separate production action until the lab approves the Pages switch.
28 changes: 28 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Check website
on:
pull_request:
push:
branches: ["codex/**"]
workflow_dispatch:
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-node@v7.0.0
with:
node-version: 24
cache: npm
- run: npm ci
- uses: actions/setup-python@v7.0.0
with:
python-version: '3.12'
- run: npm run check
- run: npm run test:skeleton
- uses: actions/upload-artifact@v7.0.1
with:
name: website-preview
path: out
include-hidden-files: true
38 changes: 38 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Manual until the lab approves switching production to React.
# After the first approved deployment, add a push trigger for master if desired.
name: Deploy React website
on:
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
deploy:
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-node@v7.0.0
with:
node-version: 24
cache: npm
- run: npm ci
- uses: actions/setup-python@v7.0.0
with:
python-version: '3.12'
- run: npm run check
- uses: actions/configure-pages@v6.0.0
- uses: actions/upload-pages-artifact@v5.0.0
with:
path: out
include-hidden-files: true
- name: Deploy
id: deployment
uses: actions/deploy-pages@v5.0.1
70 changes: 70 additions & 0 deletions .github/workflows/discover.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Collect publication candidates
on:
workflow_dispatch:
schedule:
- cron: '17 15 * * 1'
permissions:
contents: write
pull-requests: write
actions: write
concurrency:
group: publication-review
cancel-in-progress: false
jobs:
collect:
if: vars.WEBSITE_MAINTENANCE_ENABLED == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_BRANCH: ${{ github.event.repository.default_branch }}
steps:
- uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.repository.default_branch }}
fetch-depth: 0
- uses: actions/setup-node@v7.0.0
with:
node-version: 24
cache: npm
- uses: actions/setup-python@v7.0.0
with:
python-version: '3.12'
- name: Continue the existing review branch without overwriting reviewer edits
run: |
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
branch='codex/weekly-publication-review'
if git show-ref --verify --quiet "refs/remotes/origin/$branch"; then
git switch -c "$branch" "origin/$branch"
git merge --no-edit "origin/$BASE_BRANCH"
else
git switch -c "$branch"
fi
- uses: actions/cache/restore@v6.1.0
with:
path: .cache
key: discovery-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: discovery-
- run: npm ci
- name: Validate enabled configuration
run: |
python3 scripts/validate-maintenance.py
python3 -c "import json; assert json.load(open('maintenance/config.json'))['enabled'], 'Enable maintenance/config.json before activation'"
- name: Discover candidates
env:
OPENALEX_API_KEY: ${{ secrets.OPENALEX_API_KEY }}
run: python3 scripts/publication_pipeline.py collect
- run: npm run check
- name: Publish review branch and request checks
run: python3 scripts/publish_batch.py
- uses: actions/cache/save@v6.1.0
with:
path: .cache
key: discovery-${{ github.run_id }}-${{ github.run_attempt }}
- uses: actions/upload-artifact@v7.0.1
with:
name: review-preview
path: out
include-hidden-files: true
retention-days: 14
22 changes: 22 additions & 0 deletions .github/workflows/health.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Check maintenance health
on:
workflow_dispatch:
schedule:
- cron: '43 16 * * *'
permissions:
actions: read
contents: read
pull-requests: read
jobs:
health:
if: vars.WEBSITE_MAINTENANCE_ENABLED == 'true'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: '3.12'
- run: python3 scripts/monitor.py
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 changes: 11 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
_site/*
_theme_packages/*

Thumbs.db
node_modules/
.next/
out/
_review/
.DS_Store
__pycache__/
*.pyc
.env*
!.env.example

!.gitkeep

.rbenv-version
.rvmrc

.sass-cache
.jekyll-metadata
.jekyll-cache

biblib/__pycache__

Gemfile.lock
# Machine-local pre-migration recovery inventory
_planning/migration-backup.json

__pycache__
.cache/
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
23 changes: 23 additions & 0 deletions CODEBASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Codebase map

- `app/`: static Next.js pages, metadata, responsive CSS, and legacy route aliases.
- `components/`: React navigation, publication filters/cards, related awards, news and projects.
- `content/`: public JSON records, Markdown page prose, and site configuration. New editorial collections start empty.
- `lib/`: content loading, relationship resolution, filters, citation formatting, and validation.
- `public/`: original assets at historical URL paths; only public files belong here.
- `maintenance/`: verified identity/configuration slots and a public review queue; discovery starts disabled.
- `scripts/discovery.py`: paginated OpenAlex retrieval, normalization, deduplication and review proposals.
- `scripts/review.py`: local accept/reject/defer/reopen decisions; no publishing.
- `scripts/publication_pipeline.py`: repeatable collect/status/decide/check/publish entry point with a dedicated review branch and draft PR.
- `scripts/publish_batch.py`: CI review-branch/draft-PR handoff, with no merge operation.
- `scripts/monitor.py`: read-only health check suitable for an independent scheduler.
- `scripts/prepare_publication.py`: separate one-off Crossref DOI helper.
- `scripts/validate-*`, `check-export.py`, `export-aliases.mjs`: build-time contracts and URL preservation.
- `scripts/test-skeleton.py`: isolated fixture build for future sections without modifying content.
- `tests/`: content/relationship tests and review/provider failure cases using synthetic fixtures.
- `.github/`: contribution forms, PR template, CI, gated discovery/health and manual deployment workflows.
- `.agents/skills/publication-review/`: repository-scoped instructions for evidence-based recurring paper review.
- `docs/`: content model and operational/activation/rollback runbook.
- `_planning/`: roadmap, issues, migration report, and historical research.

Start with README.md. No Jekyll, Ruby runtime, database, or production application server is required.
2 changes: 0 additions & 2 deletions Gemfile

This file was deleted.

Loading