Skip to content

[scanner] sync-hive-docs heal mode produces refresh PRs that fail the #616 nav guard #624

Closed

Description

@hivecommons-hive

Summary

Heal mode in scripts/sync-hive-docs.ts (#618, enabled in the daily refresh by #620) appends every drifted upstream page to scripts/sync-hive-docs.files.json and syncs it — but it never adds the page to NAV_STRUCTURE_HIVE in src/app/docs/page-map.ts. The nav guard added by #616 (src/__tests__/page-map-adr-nav-drift.test.ts, "lists every synced page in NAV_STRUCTURE_HIVE") requires every target ?? source in the files list to appear in that nav slice. So the first time the scheduled refresh actually heals anything, the resulting bot/hive-docs-refresh PR fails the required Run unit tests (vitest) check and cannot merge — and because peter-evans/create-pull-request regenerates that single branch daily, the refresh stays red until a human hand-edits the nav.

The two features are individually correct but contradict each other; the self-heal is currently self-defeating.

Evidence (main @ 9a8bbd6)

  • scripts/sync-hive-docs.ts healFilesList() / main() — writes FILES_LIST_PATH only; nothing touches page-map.ts:
    export function healFilesList(
    list: SyncFile[],
    drift: DriftEntry[]
    ): SyncFile[] {
    return [
    ...list,
    ...drift.map(e => {
    const target = e.source.replace(/(^|\/)README\.md$/, "$1readme.md");
    return target === e.source
    ? { source: e.source }
    : { source: e.source, target };
    }),
    ];

    if (heal && drift.length) {
    healed = drift;
    const added = healFilesList(files, drift).slice(files.length);
    for (const f of added) {
    files.push(f);
    registerPage(f, true);
    }
    // Re-sync everything: links to the new pages now resolve to site routes.
    refs = new Map();
    await syncFiles(files, cache, refs);
    const listPath = path.join(process.cwd(), FILES_LIST_PATH);
    fs.mkdirSync(path.dirname(listPath), { recursive: true });
    fs.writeFileSync(listPath, JSON.stringify(files, null, 2) + "\n");
    drift = detect();
    }
  • src/__tests__/page-map-adr-nav-drift.test.ts — missing must be [], with urlOnly empty:
    it("lists every synced page in NAV_STRUCTURE_HIVE", () => {
    const sync = fs.readFileSync(
    path.join(process.cwd(), "scripts/sync-hive-docs.ts"),
    "utf8"
    );
    const map = fs.readFileSync(
    path.join(process.cwd(), "src/app/docs/page-map.ts"),
    "utf8"
    );
    const start = map.indexOf("const NAV_STRUCTURE_HIVE");
    const end = map.indexOf("const NAV_STRUCTURE_HOTSHOT", start);
    expect(start).toBeGreaterThan(-1);
    expect(end).toBeGreaterThan(start);
    const nav = map.slice(start, end);
    // Covers both the synced files list (scripts/sync-hive-docs.files.json)
    // and every `source:` entry in the sync script (`localHiveDocs`): local
    // hive pages must be in the nav too.
    const listed: Array<{ source: string; target?: string }> = JSON.parse(
    fs.readFileSync(
    path.join(process.cwd(), "scripts/sync-hive-docs.files.json"),
    "utf8"
    )
    );
    const targets = [
    ...listed.map(f => f.target ?? f.source),
    ...[
    ...sync.matchAll(/source:\s*"([^"]+)"(?:,\s*target:\s*"([^"]+)")?/g),
    ].map(m => m[2] ?? m[1]),
    ];
    // Pages intentionally reachable by URL only; add a comment per entry.
    const urlOnly = new Set<string>([]);
    expect(targets.length).toBeGreaterThan(0);
    const missing = targets.filter(
    t => !urlOnly.has(t) && !nav.includes(`'${t}'`)
    );
    expect(missing).toEqual([]);
    });
  • .github/workflows/hive-docs-refresh.yml — add-paths is only docs/content + scripts/sync-hive-docs.files.json, so even a nav edit made during the run would not be committed; REQUIRED_CHECK_WORKFLOWS includes vitest.yml:
    # branch (see "Trigger required checks" below).

    # instead (same approach as meeting-recordings-refresh.yml).
    token: ${{ secrets.GITHUB_TOKEN }}
    signoff: true

Not yet observed in a live run (the first post-#620 cron at 06:17Z has not fired as of filing), but the failure is deterministic from the code: any non-empty healed list produces a files-list entry with no nav entry.

Decision taken by hive

Simplest additive, backward-compatible option: make heal mode complete the job it starts.

  1. In scripts/sync-hive-docs.ts heal mode, after appending to the files list, also append one { '<Title>': '<target>' } entry per healed page to the last section of NAV_STRUCTURE_HIVE in src/app/docs/page-map.ts (title derived from the page's first # heading, falling back to the filename), inserted just before that section's closing ]. Keep it a text edit scoped by the existing const NAV_STRUCTURE_HIVE … const NAV_STRUCTURE_HOTSHOT markers the guard already relies on; idempotent (skip targets already present as '<target>').
  2. Add src/app/docs/page-map.ts to add-paths in hive-docs-refresh.yml so the nav edit ships in the same refresh PR.
  3. Unit-test the nav insertion (new entry appended, existing entry not duplicated, README→readme target used) alongside the existing sync-hive-docs.drift.test.ts.

Report-only mode (PR builds / prebuild) is unchanged. Rejected alternatives: relaxing the #616 guard to skip healed pages (reintroduces the nav holes #616 fixed), or dropping heal mode (reintroduces #612).

Severity: medium — blocks the daily mirror refresh from merging on the first real heal; no data loss.

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

Activity

  1. added
    agent/scannerCreated by Hive for agent-filed issue provenance
    kind/bugCreated by Hive for agent-filed issue provenance
    on Nov 5, 2026
  2. hivecommons-hive commented on Nov 5, 2026

    @hivecommons-hive
    ContributorAuthor

    🔓 Claim by agent scanner released (needs-human).

    Claim history
    • 2026-11-05 05:10 UTC — claimed by Karibhou (contributor on hive hosted-available-oke-11-placeholder-r05x)
    • 2026-11-05 05:36 UTC — released by Karibhou (contributor; lease revoked)
    • 2026-11-05 05:48 UTC — claimed by scanner (agent on hive hosted-available-oke-11-placeholder-r05x)
    • 2026-11-05 07:12 UTC — released by scanner (agent; needs-human)
  3. 2 remaining items

  4. hivecommons-hive commented on Nov 5, 2026

    @hivecommons-hive
    ContributorAuthor

    A merged PR referenced this issue without closing it. Carrying the remainder back here so the issue timeline shows what is still open.

    Remainder from the PR body:

    workflow edit to add-paths in hive-docs-refresh.yml requires the workflows permission the hive App lacks

    This comment is edited in place by the task-list sweep on every cycle; it is not duplicated.

  5. hivecommons-hive commented on Nov 5, 2026

    @hivecommons-hive
    ContributorAuthor

    What to reply

    • /hive approve: go with the recommendation
    • /hive decision <your instructions>: go ahead, following your instructions
    • /hive help: show these again

    If what this issue waited on has been done (a merged fix, or an action taken outside this repository), a maintainer can reply /fixed to close it as completed; Hive clears its park labels.

    Only a maintainer with write access can un-park; everything else is ignored. Full command reference: https://github.com/hivecommons/hive/blob/v5/src/docs/maintainer-commands.md.

  6. added
    hive/partially-addressedA merged PR addressed only part of this issue; remainder still actionable
    stage/045-needs-decisionIssue parked on a person: needs-human or a maintainer decision is owed before the hive picks it up
    stage/010-actionableTriaged; eligible for the hive to pick up
    and removed
    stage/045-needs-decisionIssue parked on a person: needs-human or a maintainer decision is owed before the hive picks it up
    stage/010-actionableTriaged; eligible for the hive to pick up
    on Nov 5, 2026
  7. clubanderson commented on Nov 5, 2026

    @clubanderson
    Member

    Fixed by #629 (merged 2026-11-05).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/scannerCreated by Hive for agent-filed issue provenancehive/partially-addressedA merged PR addressed only part of this issue; remainder still actionablekind/bugCreated by Hive for agent-filed issue provenance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions