LearnNewsExamplesServices
Frontmatter
id11590
titleAllow generated-only dev sync commits in chore hook
stateClosed
labels
bugairegressionbuild
assigneesneo-gpt
createdAtMay 18, 2026, 10:22 PM
updatedAtMay 18, 2026, 10:50 PM
githubUrlhttps://github.com/neomjs/neo/issues/11590
authorneo-gpt
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 18, 2026, 10:50 PM

Allow generated-only dev sync commits in chore hook

Closedbugairegressionbuild
neo-gpt
neo-gpt commented on May 18, 2026, 10:22 PM

Context

The direct-dev GitHub workflow/content sync path is still blocked by the Husky pre-commit guard after #11582/#11583 merged. The operator reproduced the failure on dev in /Users/Shared/github/neomjs/neo while trying to commit generated resources/content/** sync output:

chore: gh workflow sync [skip ci]
Error: Sync-data leakage detected.
Branch 'dev' (in root '/Users/Shared/github/neomjs/neo') is not a designated data-sync branch (e.g., 'chore/sync-*' or 'agent/sync-*').
The following data files are staged for commit:
- resources/content/_index.json
- resources/content/archive/discussions/v8.30.0/chunk-1/discussion-5408.md
- resources/content/discussions/chunk-1/discussion-10040.md
- resources/content/discussions/chunk-1/discussion-10073.md

The Problem

#11582/#11583 restored the SyncService auto-commit path by setting NEO_SYNC_AUTOCOMMIT=1 for git commit -m "chore: ticket sync [skip ci]". That does not cover the operator's direct-dev generated sync commit surface. Renaming the commit message does not affect the failure because buildScripts/util/check-chore-sync.mjs does not inspect the commit subject; it gates only branch, staged paths, and NEO_SYNC_AUTOCOMMIT.

V-B-A evidence from the live failing checkout:

$ git -C /Users/Shared/github/neomjs/neo status --short --branch
<h2 class="neo-h2" data-record-id="4">dev...origin/dev</h2>

M  resources/content/_index.json
... 126 staged generated sync paths total

$ NEO_SYNC_AUTOCOMMIT=1 node buildScripts/util/check-chore-sync.mjs
<h1 class="neo-h1" data-record-id="5">passes</h1>

$ node buildScripts/util/check-chore-sync.mjs
Error: Sync-data leakage detected.
Branch 'dev' (in root '/Users/Shared/github/neomjs/neo') is not a designated data-sync branch ...

A generated-only staged diff on dev is legitimate for this repository's direct sync workflow. The hook currently treats it as leakage unless the caller knows to set a hidden environment variable or moves to a synthetic sync branch, which contradicts the direct-dev data-sync pipeline reality.

The Architectural Reality

Relevant surfaces:

  • .husky/pre-commit invokes node ./buildScripts/util/check-chore-sync.mjs unconditionally.
  • buildScripts/util/check-chore-sync.mjs allows chore/sync-*, agent/sync-*, or NEO_SYNC_AUTOCOMMIT=1; otherwise any staged generated resources/content/** file is rejected.
  • ai/services/github-workflow/SyncService.mjs wraps its own auto-commit with NEO_SYNC_AUTOCOMMIT=1, but that is only one commit surface.
  • package.json exposes ai:sync-github-workflow, and the repository's sync workflow is dev-branch-owned; routing generated sync commits through feature branches plus PRs is the wrong substrate for this cache data.

The Fix

Update buildScripts/util/check-chore-sync.mjs so generated-only sync-data commits on dev pass the hook, while mixed generated + source commits on dev still fail. Keep the env-var bypass for explicit automation and retain non-dev feature-branch leakage protection.

Expected shape:

  • Compute staged generated sync files and non-sync files before branch rejection.
  • Permit branch === 'dev' only when every staged path is generated sync content.
  • Reject branch === 'dev' when generated sync files are staged alongside non-sync paths.
  • Preserve existing NEO_SYNC_AUTOCOMMIT=1 strict sync-only behavior.
  • Add focused unit coverage in test/playwright/unit/ai/buildScripts/util/check-chore-sync.spec.mjs.

Acceptance Criteria

  • A staged generated-only resources/content/** diff on dev passes check-chore-sync.mjs without requiring NEO_SYNC_AUTOCOMMIT=1.
  • A mixed staged diff on dev containing generated sync files and non-sync files fails.
  • Feature branches that stage generated sync files still fail unless they use an explicit sanctioned bypass branch or NEO_SYNC_AUTOCOMMIT=1.
  • Existing chore/sync-*, agent/sync-*, and NEO_SYNC_AUTOCOMMIT=1 behavior remains covered.

Out of Scope

  • Changing the GitHub workflow sync data model.
  • Changing GraphQL retry behavior from #11585/#11587.
  • Changing generated resources/content/** output.
  • Introducing PR-based review flow for routine generated sync data commits.

Avoided Traps

  • Do not key behavior off commit message text. The hook executes before the commit object exists and message renames are not a reliable authorization primitive.
  • Do not require direct-dev generated sync output to go through feature branches; that moves regeneratable cache updates into the human PR lane.
  • Do not broadly allow all dev commits through the hook. The permission must be generated-only.

Related

  • #11580 — original branch-context / automated-sync hook bug report
  • #11582 / #11583 — prior fix for SyncService direct-dev auto-push path
  • #11585 / #11587 — GraphQL transient retry path

Origin Session ID: 8591bc48-0ddc-48bf-aa47-58e53ea81a57

Retrieval Hint: check-chore-sync NEO_SYNC_AUTOCOMMIT dev generated-only Sync-data leakage

tobiu referenced in commit 6e0ce40 - "fix(build): bypass hooks for data sync commits (#11590) (#11592) on May 18, 2026, 10:50 PM
tobiu closed this issue on May 18, 2026, 10:50 PM