Skip to content

Ship the two guards three repos hand-rolled: the static readonly title scanner and sourceStubs.ts (they have now diverged in behaviour) #876

Description

@sroussey

Two contracts libs owns are enforced by copies living in downstream repos, and both sets of copies have drifted.

1. The static readonly title guard — the copies now enforce different rules

@workglow/task-graph requires every task class to declare static readonly title (the CLI progress UI labels rows with it). libs ships no assertion for it, so two downstreams wrote their own regex scanner:

file regex
workglow-dev/secsrc/task/taskTitles.test.ts:66 /^\s*static (?:readonly )?title(?::\s*\w+)? = "([^"]*)"/
sroussey/embarc-datasrc/taskTitles.test.ts:26 /^\s*(?:(?:public|protected|private)\s+)?static\s+(?:override\s+)?(?:readonly\s+)?title(?:\s*:\s*\w+)?\s*=\s*"([^"]*)"/

embarc's copy grew a documented fix that sec's did not receive — "a class extending a base that already declares title writes public static override title, and reading that as 'no title' would report a titled task as untitled." So sec's guard silently reads public static override title as "no title", and the two now disagree about what satisfies one libs convention. On 08-24 they differed only in header and path roots; this is a behavioural divergence.

Ask: export the assertion from @workglow/task-graph (e.g. assertEveryTaskDeclaresTitle(dir) or, better, a registry-walking check that needs no regex at all — TaskRegistry already holds the constructors), and let both downstreams delete their scanners.

2. sourceStubs.ts — two copies, drifted by the same six lines for a third cycle

md5  d17ea5c005079fc7f66c1202050ad4ca  libs/scripts/lib/sourceStubs.ts   (197 lines)
md5  a52fa2fff04c19eeed06e1ff248ffbe7  sec/scripts/sourceStubs.ts        (191 lines)

The delta is exactly the doc block libs added at fea0c8151 explaining why type stubs break under TypeScript project references. Both carry the @workglow-source-stub sentinel that scripts/publish-workspaces.ts:87-96 and sec/scripts/checkPackedContents.ts refuse a publish on — i.e. a shared invariant implemented twice. Nothing tests that they agree.

Ask: publish the module (a @workglow/dev-scripts entry, or a subpath off an existing package) and have sec import it; failing that, a test in either repo asserting the two files are identical.

Why this is worth doing now

The consolidation pattern is established and has worked twice in two windows:

  • afef1c109 moved the whole workglow binary body into a published runWorkglowCli, and workglow.ts became two statements; sec and embarc both call it rather than copying it.
  • This window, @workglow/sec exported defineStorage and embarc deleted 86 lines of its own definer to take it — naming the drift its copy had accumulated in the commit message, with sec adding storageRegistry.portability.test.ts to pin the shape upstream.

These two guards are the same shape and much smaller. Adjacent leftovers on the same list, for context rather than as asks here: four bun link scripts (72 / 180 / 175 / 228 LOC), two scoreExtraction implementations (#861), and the 105 MB s1 fixture corpus duplicated between sec and embarc with no --check (sroussey/embarc-data#68, cycle 6).

Found during the 2026-08-31 review. Snapshot: workglow-dev/prdanalysis/grades/2026-08-31/cross-repo-integration.md.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions