Context
Two adapters compile the same FocusManifestPolicy source into the same RepoPolicyCompilerOutput.labelPolicy shape and disagree on one field:
compileRepoPolicyCompilerOutput in src/signals/repo-policy-compiler.ts (lines 19-44) — used by the direct onboarding-pack API route (/repos/:fullName/onboarding-pack) and the MCP onboarding-pack tool, via src/services/repo-onboarding-pack.ts:
labelPolicy: {
preferredLabels: policy.publicSafe.labelPolicy.preferredLabels,
requiredLabels: [],
discouragedLabels: [],
note: labelPolicyNote(policy.publicSafe.validation.linkedIssuePolicy),
},
focusManifestPolicyToCompilerOutput in src/signals/onboarding-pack.ts (lines 84-105) — used by src/signals/registration-readiness.ts (line ~173-174, buildRegistrationReadiness's onboardingPackPreview computation):
labelPolicy: {
preferredLabels: policy.publicSafe.labelPolicy.preferredLabels,
requiredLabels: [],
discouragedLabels: [],
},
focusManifestPolicyToCompilerOutput's own doc comment says it adapts a compiled FocusManifestPolicy "into the RepoPolicyCompilerOutput shape expected by buildRepoOnboardingPackPreview" — implying it should produce an equivalent output to compileRepoPolicyCompilerOutput for the same manifest — but it omits the note field entirely, so labelPolicy.note comes out undefined (rendered as null wherever the report is serialized).
Effect: the registration-readiness report's onboardingPackPreview.labelPolicy (surfaced to repo owners evaluating whether to register) always shows note: null, silently losing the linked-issue-policy guidance text (e.g. "Link a tracked issue before opening a pull request.") that the same manifest would produce via the direct onboarding-pack API/MCP path.
No test calls focusManifestPolicyToCompilerOutput directly (verified via a repo-wide grep across test/** for the function name), so this drift between the two adapters is untested.
Requirements
focusManifestPolicyToCompilerOutput must populate labelPolicy.note with the same value compileRepoPolicyCompilerOutput would produce for an equivalent linkedIssuePolicy — currently computed by the private labelPolicyNote(linkedIssuePolicy: string) helper (src/signals/repo-policy-compiler.ts lines 114-118).
labelPolicyNote is currently unexported and repo-policy-compiler.ts already has a type-only import from onboarding-pack.ts (import type { RepoPolicyCompilerOutput, RepoPolicyContributionLane } from "./onboarding-pack"). Two acceptable approaches:
- Add
export to labelPolicyNote in repo-policy-compiler.ts and import it as a value in onboarding-pack.ts (safe here since the existing reverse import is type-only and erased at compile time, so this does not create a real runtime cycle) — the more minimal diff; or
- Move
labelPolicyNote into src/signals/focus-manifest.ts (already imported by both files) as a shared export, and update both call sites.
Pick whichever keeps the diff smallest and cleanest; either is acceptable.
- Do not change
labelPolicyNote's logic (the three linkedIssuePolicy branches) — reuse it as-is, don't reimplement or duplicate its string literals.
- Do not change any other field mapping in
focusManifestPolicyToCompilerOutput (contributionLanes, validationExpectations, readinessWarnings, privateOwnerContext) — this fix is scoped strictly to the missing labelPolicy.note.
Deliverables
Test Coverage Requirements
Aim for 99%+ Codecov patch coverage (100% including the new branch/invariant) on the touched lines in src/signals/onboarding-pack.ts. This is a fix for real information loss on a live report path, so the cross-adapter parity regression test is required, not just incidental line coverage.
Expected Outcome
The registration-readiness report's onboardingPackPreview.labelPolicy.note carries the same linked-issue-policy guidance text a repo owner would see via the direct onboarding-pack API/MCP tool, instead of always being null.
Links & Resources
src/signals/onboarding-pack.ts (focusManifestPolicyToCompilerOutput, lines 84-105)
src/signals/repo-policy-compiler.ts (compileRepoPolicyCompilerOutput, lines 19-44; labelPolicyNote helper — the precedent to mirror)
src/signals/registration-readiness.ts (buildRegistrationReadiness, onboardingPackPreview computation, ~lines 168-174)
test/unit/onboarding-pack.test.ts, test/unit/registration-readiness.test.ts (existing test suites)
Context
Two adapters compile the same
FocusManifestPolicysource into the sameRepoPolicyCompilerOutput.labelPolicyshape and disagree on one field:compileRepoPolicyCompilerOutputinsrc/signals/repo-policy-compiler.ts(lines 19-44) — used by the direct onboarding-pack API route (/repos/:fullName/onboarding-pack) and the MCP onboarding-pack tool, viasrc/services/repo-onboarding-pack.ts:focusManifestPolicyToCompilerOutputinsrc/signals/onboarding-pack.ts(lines 84-105) — used bysrc/signals/registration-readiness.ts(line ~173-174,buildRegistrationReadiness'sonboardingPackPreviewcomputation):focusManifestPolicyToCompilerOutput's own doc comment says it adapts a compiledFocusManifestPolicy"into theRepoPolicyCompilerOutputshape expected bybuildRepoOnboardingPackPreview" — implying it should produce an equivalent output tocompileRepoPolicyCompilerOutputfor the same manifest — but it omits thenotefield entirely, solabelPolicy.notecomes outundefined(rendered asnullwherever the report is serialized).Effect: the registration-readiness report's
onboardingPackPreview.labelPolicy(surfaced to repo owners evaluating whether to register) always showsnote: null, silently losing the linked-issue-policy guidance text (e.g. "Link a tracked issue before opening a pull request.") that the same manifest would produce via the direct onboarding-pack API/MCP path.No test calls
focusManifestPolicyToCompilerOutputdirectly (verified via a repo-wide grep acrosstest/**for the function name), so this drift between the two adapters is untested.Requirements
focusManifestPolicyToCompilerOutputmust populatelabelPolicy.notewith the same valuecompileRepoPolicyCompilerOutputwould produce for an equivalentlinkedIssuePolicy— currently computed by the privatelabelPolicyNote(linkedIssuePolicy: string)helper (src/signals/repo-policy-compiler.tslines 114-118).labelPolicyNoteis currently unexported andrepo-policy-compiler.tsalready has a type-only import fromonboarding-pack.ts(import type { RepoPolicyCompilerOutput, RepoPolicyContributionLane } from "./onboarding-pack"). Two acceptable approaches:exporttolabelPolicyNoteinrepo-policy-compiler.tsand import it as a value inonboarding-pack.ts(safe here since the existing reverse import is type-only and erased at compile time, so this does not create a real runtime cycle) — the more minimal diff; orlabelPolicyNoteintosrc/signals/focus-manifest.ts(already imported by both files) as a shared export, and update both call sites.Pick whichever keeps the diff smallest and cleanest; either is acceptable.
labelPolicyNote's logic (the threelinkedIssuePolicybranches) — reuse it as-is, don't reimplement or duplicate its string literals.focusManifestPolicyToCompilerOutput(contributionLanes,validationExpectations,readinessWarnings,privateOwnerContext) — this fix is scoped strictly to the missinglabelPolicy.note.Deliverables
focusManifestPolicyToCompilerOutputsetslabelPolicy.notevialabelPolicyNote(...), matchingcompileRepoPolicyCompilerOutput's behavior.FocusManifestinput,focusManifestPolicyToCompilerOutput(compileFocusManifestPolicy(...))andcompileRepoPolicyCompilerOutput(...)produce the same non-nulllabelPolicy.notevalue.buildRegistrationReadiness'sonboardingPackPreview.labelPolicy.noteend-to-end (intest/unit/registration-readiness.test.ts) confirming it is no longer alwaysnullwhen a manifest with a non-"off"linkedIssuePolicyis supplied.Test Coverage Requirements
Aim for 99%+ Codecov patch coverage (100% including the new branch/invariant) on the touched lines in
src/signals/onboarding-pack.ts. This is a fix for real information loss on a live report path, so the cross-adapter parity regression test is required, not just incidental line coverage.Expected Outcome
The registration-readiness report's
onboardingPackPreview.labelPolicy.notecarries the same linked-issue-policy guidance text a repo owner would see via the direct onboarding-pack API/MCP tool, instead of always beingnull.Links & Resources
src/signals/onboarding-pack.ts(focusManifestPolicyToCompilerOutput, lines 84-105)src/signals/repo-policy-compiler.ts(compileRepoPolicyCompilerOutput, lines 19-44;labelPolicyNotehelper — the precedent to mirror)src/signals/registration-readiness.ts(buildRegistrationReadiness,onboardingPackPreviewcomputation, ~lines 168-174)test/unit/onboarding-pack.test.ts,test/unit/registration-readiness.test.ts(existing test suites)