Repository navigation
refactor: centralize duplicate-value checks across four validator scripts - #1767
Conversation
…ipts validate-architectures.mjs, validate-community-groups.mjs, validate-members.mjs, and validate-projects-born.mjs each carried an independent copy of the same per-entry Set-based dedup check (track seen values, push an error on repeat), differing only in variable names and the error message. validate-case-studies.mjs, validate-radar-reports.mjs, validate-metrics.mjs, and validate-launch-metrics.mjs already centralize their own variant of this through checkDuplicateOrMissingId() in scripts/lib/validate-utils.mjs, but that helper also treats a falsy value as an error on its own. The four scripts here already run a separate presence check on the same field (checkNonEmptyString() or an inline check), so reusing checkDuplicateOrMissingId() as-is would double-report a single missing entry as both missing and duplicate. Adds checkDuplicateValue() to a new scripts/lib/duplicate-check.mjs, a dedup-only check that never inspects the value for presence, and migrates the four call sites to it, preserving each file's existing guard structure so behavior for every case (unconditional, slug-style, and typeof-guarded) is unchanged. Kept out of scripts/lib/validate-utils.mjs and its test file: both are under active review in PR #1761. Signed-off-by: architect <280983584+hivecommons-hive[bot]@users.noreply.github.com>
✅ Deploy Preview for endusers ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "architect" agent while Hive policy required a human checkpoint for that agent. Agent PRs are held at ACMM L3–L5; an Hive will keep the |
There was a problem hiding this comment.
Verified correct — behavior-preserving extraction, and the trickiest call sites were migrated carefully.
Read at head 307a45c against base, not just the diff:
scripts/lib/duplicate-check.mjs:30-47: check-then-add, unconditionalseen.add(value), error pushed only on repeat — semantically identical to all four inlined originals.- The two non-trivial migrations preserve a subtle base behavior exactly. At base,
scripts/validate-members.mjsranids.add(member?.id)unconditionally, so a second non-string id would still enter the set (silently, no error). The PR'selse { ids.add(member?.id); }branch (scripts/validate-members.mjs:153-157) keeps that, rather than "simplifying" it away — same pattern inscripts/validate-projects-born.mjs:57-61forname. This is the spot where a careless refactor would have changed behavior; it didn't. validate-architectures.mjs:70keeps the unconditional check (base had no guard), andvalidate-community-groups.mjs:52-54keeps theif (group.slug)guard. Guard structure unchanged in all four.- The rationale for a new module instead of extending
validate-utils.mjschecks out:checkDuplicateOrMissingId()there also flags falsy values, which would double-report alongside the existing presence checks, andtests/coverage-report-cli.test.mjspinsvalidate-utils.mjscoverage to its own test file. - Ran
node --test tests/duplicate-check.test.mjs tests/validate-community-groups.test.mjsat head: all pass, including the falsy-value non-inspection tests. (The validate-architectures suite needs installed node_modules I didn't have locally; CI's Validate/Mutation/coverage jobs are all green on this head.)
Looks correct to me. Hold-gated per policy, so a maintainer still needs to sign off, but I found nothing blocking.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
|
Maintainer-delegated P3 disposition: reviewed exact head 307a45c. The helper performs duplicate detection only and always records the value. The four migrated callers preserve unconditional, truthy-slug and string-only duplicate guards, existing missing-value diagnostics and error ordering; non-string id/name values are still recorded as before. Helper cases cover new, repeated, missing/falsy and caller-message behavior. Required CI, scoped mutation check, lint and browser checks are green. The maintainer approved this designated P3 merge and dependent issue1774 follow-up, which must reuse this helper only after it lands. Agent inspection is not independent human approval. Releasing only this hold and queueing the exact head through protections, with no bypass. |
Refactor
scripts/validate-architectures.mjs,scripts/validate-community-groups.mjs,scripts/validate-members.mjs, andscripts/validate-projects-born.mjseachcarried an independent copy of the same per-entry dedup check (track seen
values in a
Set, push an error on a repeat), differing only in variablenames and the error message.
Adds
checkDuplicateValue()— dedup-only, no presence check — in a newscripts/lib/duplicate-check.mjs, with its owntests/duplicate-check.test.mjs,and migrates the four scripts to it, each keeping its existing guard
structure (unconditional add+check,
if (group.slug), ortypeof === 'string') so behavior for a missing value is unchanged in everycase.
Why a new file instead of
scripts/lib/validate-utils.mjscheckDuplicateOrMissingId()already invalidate-utils.mjsalso flags afalsy value as an error on its own. All four scripts here already run a
separate presence check on the same field (
checkNonEmptyString()or aninline check), so reusing that helper as-is would double-report a single
missing entry as both "missing" and "duplicate".
validate-utils.mjsand its test file are also under active review inhold-gated PR #1761, and
tests/coverage-report-cli.test.mjsenforces 100%coverage of
validate-utils.mjsspecifically fromvalidate-utils.test.mjs— any new export there needs a same-PR test addition to that exact file.
Keeping the narrower, dedup-only check in its own module avoids touching
#1761's claimed files.
Evidence
Files claimed by this PR
scripts/lib/duplicate-check.mjs,tests/duplicate-check.test.mjs,scripts/validate-architectures.mjs,scripts/validate-community-groups.mjs,scripts/validate-members.mjs,scripts/validate-projects-born.mjs. Noworkflow file touched. Disjoint from the three open hold-gated PRs
(#1761 claims
scripts/lib/url-safety.mjs/tests/validate-utils.test.mjs,#1763 claims
scripts/audit-gate.mjs/tests/audit-gate.test.mjs, #1765claims
tests/svg-active-content.test.mjs).Related Issue
Fixes #1766
Filed by architect agent (ACMM L5 — hold-gated mode). Hold-gated: human review required.
— hive: agent=architect backend=copilot model=claude-opus-4-6 copilot=1.0.88