Related Docs: Appverse Contributor Guide | Appverse Security Rubric | Appverse Best Practices | Appverse README Template
A guide for reviewers evaluating whether a new app should be included in the Appverse catalog.
Overview
The goal of review is to ensure that apps in the catalog are useful, deployable, and maintainable by the broader HPC community. We're not looking for perfection — we're looking for apps that meet a quality bar and don't create confusion in the catalog.
Decision Framework
Should This App Exist in the Catalog?
Ask these questions first, before evaluating quality:
| Question | If No... |
|---|---|
| Does this app serve software not already in the catalog? | See "Duplicate Check" below |
| Is the repository public and accessible? | Cannot be included — public repo required |
| Does it have an open source license? | Cannot be included — license required |
| Is there a maintainer who will respond to issues? | Flag as a risk — orphaned apps hurt the catalog |
Duplicate Check
If the software already has apps in the catalog:
- Same app, different site config → Reject. Encourage the contributor to document their configuration in the existing app or contribute changes upstream.
- Same app, forked with minor changes → Reject unless the fork adds significant new capability. Encourage contributing back upstream.
- Same software, meaningfully different approach → Accept. Examples: containerized vs. module-based, GPU vs. CPU, different execution model (e.g., AlphaFold 2 vs. AlphaFold 3 support).
Document the rationale either way — the review report has a duplicate-check rationale field under "Not checked" for this; fill it in before pasting the feedback into the issue or email.
Reading the catalog without a login
The catalog is a Drupal site with JSON:API enabled and readable anonymously, so the Software entry, the vocabularies and the published app list can all be checked from the command line — no reviewer account needed.
Two things will make these look like an unreachable host if you get them wrong.
Follow redirects (-L), or the request returns 000. And percent-encode the
query brackets as %5B/%5D — a URL with literal [ is dropped before it
reaches Drupal and yields an empty response with no status code at all.
# Does a Software entry exist for this app's `software` value?
curl -sL -H 'Accept: application/vnd.api+json' \
'https://openondemand.connectci.org/jsonapi/node/appverse_software?filter%5Btitle%5D=API%20Access&fields%5Bnode--appverse_software%5D=title'
# The implementation-tags vocabulary (matching is case-insensitive)
curl -sL -H 'Accept: application/vnd.api+json' \
'https://openondemand.connectci.org/jsonapi/taxonomy_term/appverse_implementation_tags?fields%5Btaxonomy_term--appverse_implementation_tags%5D=name&page%5Blimit%5D=50'
# Published apps, for the duplicate check
curl -sL -H 'Accept: application/vnd.api+json' \
'https://openondemand.connectci.org/jsonapi/node/appverse_app?fields%5Bnode--appverse_app%5D=title&page%5Blimit%5D=100'
Sibling resources on the same API: taxonomy_term--appverse_app_type,
taxonomy_term--appverse_license, node--appverse_repo. GET /jsonapi lists
everything available.
Writing still needs a login — creating a Software entry, moderating an app. Reading does not, so report these checks as performed rather than deferred.
Software Entry Check
The app's software value must match a Software entry in the catalog or the app
won't be listed. Software is its own catalog node type, created separately from
the app — the app form only references an existing Software entry, it cannot
create one. Query for it with the command above. If there is no matching entry,
it is the reviewer's decision, not an automatic failure:
- Software should exist in the catalog → create the Software entry first using the Add Appverse Software form (reviewer login required), then the app can reference it and list.
- Typo, or maps to an existing entry under a different name → ask the
contributor to correct the
softwarevalue. - Not appropriate for the catalog → Request changes, with the reason.
Declared vs. Inferred Repos and Monorepos
A repo with a root appverse.yml is declared: the contributor states how their
app(s) appear in the catalog. A repo with only a root manifest.yml is inferred:
the catalog derives a single app from that file plus GitHub metadata.
A declared repo whose appverse.yml has an apps: list is a Monorepo. Review
every entry in apps[] as its own app — each gets its own structure, security, and
quality assessment, and its own decision. Per-app fields resolve with this precedence:
- Inline in the root
appverse.ymlapps[]entry (highest) <subpath>/appverse.yml<subpath>/manifest.yml(name/description fallback only)
Directories listed in shared_paths are shared code: review them once at repo level
and include them in the security review. Decisions can differ per app — e.g., accept
three apps and request changes on a fourth.
Required Criteria
All of these must be met for inclusion. These are pass/fail.
1. Repository Structure
Every repo, regardless of shape:
| Check | What to Look For |
|---|---|
README.md exists |
Is substantive (not just a title) — see Documentation section |
LICENSE exists |
Open source license present (MIT recommended) |
| Repo shape is identifiable | Root appverse.yml (declared) or root manifest.yml (inferred) — see "Declared vs. Inferred Repos and Monorepos" above |
Inferred repos (root manifest.yml, no appverse.yml):
| Check | What to Look For |
|---|---|
manifest.yml required fields |
name, category, role, description at minimum |
Declared repos (root appverse.yml), checked per app after field-precedence resolution:
| Check | What to Look For |
|---|---|
description |
Present |
software |
Present (checked here). It must also match a catalog Software entry to be listed — see Software Entry Check for what to do when it doesn't |
app_type |
A known value (see the appverse.yml reference) |
maintainer.name + maintainer.support_url |
Both required and present. An app without a support URL gives deployers no one to contact — a missing one is a required-criteria failure |
manifest.yml at the app's subpath |
Required for the app to actually run inside OOD |
For Batch Connect Apps: standard OOD structure with expected files (form.yml or form.yml.erb, submit.yml.erb, template/). OOD renders form.yml.erb at request time, so an app shipping only the .erb variant is complete; shipping both is unusual and worth a look
2. Documentation Minimum
The README should follow the Appverse README Template structure. At minimum, it must answer these questions for an HPC admin who has never seen the app:
| Question | Where to Find It |
|---|---|
| What does this app launch? | Overview section |
| What needs to be installed on compute nodes? | Requirements section and Software Installation in References section |
| How do I deploy it? | Installation section |
| What do I need to customize? | Configuration section |
Red flags:
- README is still the unfilled template (placeholder text like "Key feature 1" still present)
- README only contains a project name and/or contact email
- README references a different institution's paths without noting they need to change
- No Configuration section — deployers can't tell what to customize
3. Security Concerns
Security review follows the dedicated Appverse Security Rubric: build a capability profile for the app's type, run the pattern checks, and classify findings under the OODT taxonomy. The three legacy spot-checks (committed credentials, disabled security without justification, user input reaching shell commands) are all covered by the rubric's pattern checks.
4. Basic Functionality
| Check | What to Look For |
|---|---|
form.yml or form.yml.erb is valid |
form.yml parses without errors; form.yml.erb has balanced ERB tags (it cannot be YAML-parsed directly) |
manifest.yml is valid YAML |
Parses without errors |
| Template scripts are syntactically correct | ERB templates render, shell scripts pass bash -n (for .sh.erb, strip ERB tags first — see security-tools.md). Shellcheck is a best-effort tier 2 tool — run it when available, but its absence does not fail this criterion |
| No obviously broken references | Module names, paths, and variables referenced in templates exist in form.yml or form.yml.erb |
Quality Criteria
These are evaluated on a scale. An app doesn't need to be perfect, but the more boxes checked, the better.
Documentation Quality
| Level | Description |
|---|---|
| Minimal | What it launches + prerequisites only |
| Adequate | Above + installation + configuration + known limitations |
| Strong | Above + troubleshooting + screenshots + environment variable docs |
| Exemplary | Above + user-facing info panel + architecture explanation |
Target for inclusion: Adequate or above.
Configuration Portability
| Level | Description |
|---|---|
| Not portable | Hardcoded paths, cluster names, module versions throughout |
| Partially portable | Some hardcoding, but main config is in form.yml attributes |
| Portable | All site-specific values centralized and clearly marked |
Target for inclusion: Partially portable or above. If "Not portable," ask the contributor to centralize configuration before accepting.
Code Quality
| Check | Status |
|---|---|
Error handling in scripts (set -e or explicit checks) |
|
| No undocumented magic numbers or hardcoded literals (resource limits, tunables, ports, hex colors, module versions) without comments | |
| No large blocks of duplicated code | |
| No commented-out dead code | |
| Input validation on form fields (min/max/required) | |
| ERB templates handle missing/empty values gracefully |
Target for inclusion: At least error handling and input validation. Other items are improvement suggestions.
Maintenance Signals
Repo-level signals about the project's health.
| Signal | Good Sign | Concern |
|---|---|---|
| Last commit | Within 12 months | Over 2 years ago |
| Releases | Tagged releases with versioning | No releases |
| Issues | Responded to | Open issues with no response |
| Contributors | Multiple | Single contributor with no activity |
| CHANGELOG | Present and current | Missing |
| CI/CD | A workflow that lints shell/ERB or validates the YAML (.github/workflows/ or equivalent) |
None |
Target for inclusion: Active within 12 months. For brand-new apps, waive the history requirement but flag for follow-up review in 6 months.
The other signals — tagged releases, issue responsiveness, contributors, CHANGELOG, CI — are good-practice indicators, not requirements. There is no requirement to cut releases or use versioning; a release is a positive signal that the team follows good practices, and its absence is worth a suggestion, never a failure. CI is the weakest of these for an app repo: most Appverse apps are config-and-template repos with little to test beyond YAML validity and shell/ERB lint, which Appverse Review already checks — so weight a missing CI workflow low.
Review Process
Where to Find Pending Submissions
Apps awaiting review appear in the Manage Appverse Apps view in Drupal: openondemand.connectci.org/appverse/manage-apps. The view shows the submitter's name and email so you can follow up with questions, the moderation state, and a link to edit the app node.
Most of the checks below are performed by Appverse Review, which produces an evidence-backed report covering structure, security, quality, and maintenance, with file:line findings and a recommended decision. The reviewer receives this report, verifies its findings, and makes the call — the review recommends, a human decides.
Step 1: Start from the review report
Begin with the Appverse Review report for the submitted repo. Note the commit it was run against — the report pins a commit SHA, and its file:line findings are only valid for that commit. If the repo has moved on since, get a fresh report before continuing.
Step 2: Verify the findings
Read the report against the repo and confirm its findings hold, rather than taking them on trust. Spot-check that:
- Required files and metadata are as the report states —
appverse.ymlormanifest.yml,README.md,LICENSE, standard OOD structure. - Security findings are real and correctly rated — open a few and check the
cited
file:lineactually shows the flagged pattern. - Quality ratings and any correctness-&-polish findings match what you see — documentation level, portability, and any copy-paste artifacts or typos.
- Maintenance signals are current — last commit, releases, CI, CHANGELOG.
- The duplicate check is settled — the review cannot see the catalog, so this is the reviewer's to confirm (see Duplicate Check above).
Trust the report's structure but verify its substance; if a finding does not hold, correct it before it reaches the contributor.
Step 3: Decision
| Outcome | Criteria |
|---|---|
| Accept | Passes all required criteria, adequate+ documentation, partially portable+ config. Always conditional on the duplicate/catalog checks the review cannot perform — word any Accept as pending those. |
| Accept with suggestions | Passes required criteria but has clear improvement areas — include specific feedback. Below-target docs or portability belongs here, not Request changes, when required criteria are otherwise met. |
| Request changes | Missing required criteria but fixable — provide specific list of what to address. A fixable security misconfiguration, even High severity (e.g. CORS open to all origins), is Request changes, not Reject. |
| Reject | Duplicate app, no license, abandoned/unmaintained, not an OOD app, or a security finding tagged potentially malicious or unfixable without redesigning the app. |
Providing Feedback
When requesting changes or suggesting improvements, be specific:
Good feedback:
The README lists prerequisites but doesn't include installation steps. Please add a section showing how to clone and deploy the app (see ProteinStructure-OOD for an example).
Poor feedback:
README needs work.
Reference the Best Practices Guide for specific recommendations to share with contributors.
Common Issues Found in Real Apps
Based on analysis of apps currently in the Appverse:
| Issue | Frequency | Severity |
|---|---|---|
| Missing or stub README | Common | High — blocks deployment |
| No error handling in scripts | Very common | Low — causes silent failures |
| Hardcoded paths | Common | Medium — blocks portability |
| No releases or versioning | Common | Low — but makes updates risky |
| Missing CHANGELOG | Common | Low — but reduces trust |
| No troubleshooting docs | Very common | Low — but increases support burden |
| Dead/commented-out code | Occasional | Low — but confusing |
| Magic numbers without comments | Occasional | Low — but hinders maintenance |
| Security settings disabled without explanation | Rare | High — potential vulnerability |
Appendix: Review Template
Copy this template when reviewing a new app submission:
## App Review: [App Name]
**Repository:** [URL]
**Reviewed commit:** [SHA] ([date])
**Reviewer:** [Name]
**Date:** [Date]
### Required Criteria
- [ ] Required metadata fields for the repo shape (see Repository Structure)
- [ ] README.md (substantive)
- [ ] LICENSE (open source)
- [ ] Standard OOD app structure
For Monorepos: repeat the per-app criteria and decision for each entry in `apps[]`.
### Security
- Findings classified under the OODT taxonomy, with severity and file:line evidence
### Quality Assessment
- Documentation: [Minimal / Adequate / Strong / Exemplary]
- Portability: [Not portable / Partially portable / Portable]
- Code quality and correctness-&-polish findings, with file:line evidence
### Maintenance Signals
- [Active / Moderate / Inactive] — last commit, releases, CI, CHANGELOG
### Catalog Checks
- [ ] Duplicate check against the existing catalog — [outcome and rationale]
- [ ] `software` value matches a catalog Software entry (see Software Entry Check — create the entry if the software should exist)
- [ ] `app_type` and `implementation_tags` are in the catalog vocabularies
Query these against the public JSON:API — see "Reading the catalog without a
login". Record what each returned. If one could not be run, say which and why,
rather than leaving it unmarked.
### Decision: [Accept / Accept with suggestions / Request changes / Reject]
- If any catalog check above could not be run, Accept is conditional on it
### Feedback
[Specific items to address or improve — every item must already appear above]