agenticsorg / agenticsorg/community-projects
Pending-row intake: matrix-mutation silently no-ops for concurrent submissions (#52/#53), and single-file pending[] is collision-prone
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 3
- Forks
- 1
- Avg merge
- 1m
- Merged PRs (30d)
- 1
Description
Symptom
On 2026-08-21, three RobLe3 IICP submissions (#51, #52, #53) and #55 (michaeloboyle/iicp-node-monitor) all classified status:pending-review, but only #51's row auto-landed in docs/data/oia-matrix.json. #52 and #53 required a hand-carried backfill branch to get into the matrix, and that backfill itself needed two PRs in one day: PR #54 (stale branch) went CONFLICTING/DIRTY the moment #55's pending row landed on main, because both mutate the one shared docs/data/oia-matrix.json on divergent branches. PR #54 was superseded by PR #56, which regenerated #52/#53 from current main and merged.
- #54 (superseded, closed): https://github.com/agenticsorg/community-projects/pull/54
- #56 (the patch, merged): https://github.com/agenticsorg/community-projects/pull/56
This is the per-incident patch. The two root causes below are the upstream fix.
Root cause 1 — the on-submission matrix-mutation silently no-ops under concurrent submissions
#51/#52/#53 were created within 26 seconds of each other (17:44:24 / 17:44:49 / 17:44:50 UTC). Each issues event triggers pages.yml, which runs scripts/oia-intake-step.mjs -> scripts/add-pending.mjs, mutating docs/data/oia-matrix.json in a fresh checkout of main and committing back.
The persist step swallows failures (.github/workflows/pages.yml):
git commit -m "oia-matrix: auto-update from issue #... [skip ci]"
git pull --rebase --autostash origin main || true
git push || echo "push skipped (branch protection or race); deploy still reflects local tree"
Both the rebase (|| true) and the push (|| echo ...) discard their exit codes. So under concurrent submissions the sequence is a classic lost update: run A (#51) checks out main, adds its row, pushes -> main advances. Runs B/C (#52/#53) checked out the pre-A main, add their rows, and their git push is rejected non-fast-forward — but || echo swallows the rejection and the job still reports success. The mutation is silently dropped.
Evidence — all three creation-event runs report success, yet only #51's row landed:
- #51 IICP Protocol — run
32509719380success (row landed) - #52 IICP Rust Directory — run
32509755261success (row lost) - #53 IICP Rust SDK — run
32509762843success (row lost)
Then the follow-on edited/labeled runs at 17:50 were cancelled by the concurrency: group: pages queue supersession, so no retry recovered the lost rows:
- #52 IICP Rust Directory — runs
32510279116,32510279270bothcancelled - #53 IICP Rust SDK — run
32510280555cancelled
Net: the matrix-mutation "did not fire" for #52/#53 not because classification failed, but because concurrent pushes were silently rejected and the retries were cancelled by the single-flight pages concurrency group. A green run is currently conformance, not proof the row landed — the persist step needs to fail (or retry-with-rebase-until-success) on a rejected push instead of || echo.
Root cause 2 (structural) — a single committed JSON array is collision-prone by construction
add-pending.mjs appends every pending entry to one committed array in docs/data/oia-matrix.json. Two things follow mechanically:
- Workflow-level lost update (root cause 1): concurrent runs mutate the same file and race the same push.
- PR-level textual conflict: any two backfill/edit branches that both touch
pending[]collide in git (exactly why #54 conflicted with #55).
Both are symptoms of one shared mutable file on the write path. Proposed upstream fix (pick one):
- One-file-per-pending-entry — write each submission to
docs/data/pending/<slug>.json; a build step merges the directory into the served matrix at publish time. Concurrent submissions write disjoint files, so they never collide in git and never race the same array. Deletion/promotion is a file remove/move. - OR idempotent append-to-main — keep the single file but make the persist step a real fetch/rebase/re-apply loop that retries on non-fast-forward until the push succeeds (no
|| echo), so the mutation is never silently lost. This fixes root cause 1 but not the PR-level textual conflict.
The per-entry-file design addresses both root causes; the retry-loop design addresses only root cause 1. Recommend the per-entry-file design.
Frame
Task-1 patch (PR #56) restored the two rows. This issue is the upstream fix so the next batch of near-simultaneous submissions doesn't need a human to notice the silent loss and hand-carry a backfill.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read .github/workflows/pages.yml, scripts/oia-intake-step.mjs, scripts/add-pending.mjs, and docs/data/oia-matrix.json; inspect the referenced workflow runs and PRs to understand the lost update. Choose and implement an upstream design that prevents concurrent pending submissions from being silently lost or conflicting, then verify the workflow fails or retries appropriately and the published matrix retains every submission.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github-actions, javascript
- Domain
- build-system, ci-cd
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100