Skip to content

Webhook jobs silently skip incremental documentation regeneration #837

Description

@GautamSharma99

Issue description

GitHub and GitLab push webhooks enqueue jobs using an unsupported execution mode.

Both handlers create jobs with:

{
"mode": "incremental",
"trigger": "webhook"
}

However, the server job executor does not recognize incremental. It only has explicit behavior for sync, full_resync, initial_index, and
index_only.

The job still completes successfully, but documentation regeneration is skipped and the repository’s synchronization baseline is advanced.

Exact failure path

1. Webhook handlers enqueue incremental

GitHub creates the job at:

  • packages/server/src/repowise/server/routers/webhooks.py:119
  • Mode assignment: packages/server/src/repowise/server/routers/webhooks.py:124

GitLab has the same behavior:

  • packages/server/src/repowise/server/routers/webhooks.py:177
  • Mode assignment: packages/server/src/repowise/server/routers/webhooks.py:182

Both handler docstrings describe these as “sync” jobs, making the configuration inconsistent with the documented intent.

2. The executor does not recognize the mode

The executor reads the job mode here:

  • packages/server/src/repowise/server/job_executor.py:343

It only derives flags for:

is_full_resync = mode == "full_resync"
is_initial_index = mode == "initial_index"
is_index_only = mode == "index_only"

incremental matches none of these conditions.

3. Full documentation generation is disabled

The main pipeline generates documentation only for full resync and initial-index jobs:

generate_docs = (
(is_full_resync or is_initial_index)
and llm_client is not None
and bool(config.get("generate_docs", True))
)

Therefore, a webhook job calls run_pipeline() with generate_docs=False.

The repository is re-ingested and its analysis data may be updated, but no documentation pages are generated.

4. Incremental regeneration is also skipped

The executor has a separate incremental page-regeneration phase, but it runs only for sync:

  • packages/server/src/repowise/server/job_executor.py:401
  • packages/server/src/repowise/server/job_executor.py:406

if mode == "sync" and llm_client is not None:
incremental_pages = await _incremental_page_regen(...)

Because the webhook mode is incremental, this condition is false.

The webhook job therefore skips both possible documentation-generation paths.

5. The job still reports success and advances the baseline

After re-indexing, the job is marked completed, even though no documentation was regenerated.

The executor then calls _stamp_last_sync_commit() for every non-initial-index mode:

  • packages/server/src/repowise/server/job_executor.py:482
  • packages/server/src/repowise/server/job_executor.py:497

This updates state.json with the current HEAD.

The polling fallback subsequently sees HEAD == last_sync_commit and concludes that the repository is synchronized, so it does not enqueue a
corrective sync job.

Resulting behavior

Push webhook
→ "incremental" job created
→ repository re-indexed
→ documentation regeneration skipped
→ job marked completed
→ last_sync_commit advanced
→ polling fallback sees repository as current
→ stale documentation remains indefinitely

Expected behavior

A default-branch push webhook should perform the same incremental documentation refresh as a polling-triggered sync job:

  • Re-index the repository.
  • Determine which pages are affected by the pushed commits.
  • Regenerate those pages when an LLM provider is configured.
  • Persist the updated pages and search indexes.
  • Advance last_sync_commit only after the intended sync path succeeds.

Proposed implementation direction

Use the executor’s canonical sync mode in both webhook handlers:

{
"mode": "sync",
"trigger": "webhook",
"before": "...",
"after": "..."
}

For backward compatibility, the executor could also normalize existing incremental jobs to sync:

if mode == "incremental":
mode = "sync"

It would also be useful to validate modes explicitly so future unknown values fail visibly instead of silently running with partial behavior.

Test gap

Current webhook tests verify only request acceptance and authentication:

  • tests/unit/server/test_webhooks.py:15
  • tests/unit/server/test_webhooks.py:87

They do not:

  • Seed a matching repository.
  • Inspect the generated job configuration.
  • Verify the linked webhook event’s job ID.
  • Execute the generated job.
  • Assert that incremental page regeneration occurs.
  • Verify synchronization-state behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions