Skip to content
Draft
12 changes: 11 additions & 1 deletion tools/orion-ref-gate/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
findViolations,
isCarveOut,
lineHasToken,
REMEDIATION_DOC,
runOnce,
} from "./index.ts";

Expand Down Expand Up @@ -159,7 +160,16 @@ describe("runOnce", () => {
expect(code).toBe(1);
const e = errs.join("\n");
expect(e).toContain("docs/x.md:7");
expect(e).toContain("skill://private-repo-boundary");
expect(e).toContain("the managed service");
expect(e).toContain(REMEDIATION_DOC);
});

test("the doc cited in the failure hint exists", async () => {
// Resolved from this file, not the cwd, so the assertion holds under any
// invocation. Without it the hint can silently die in a docs move —
// the defect this pointer was repaired for.
const abs = new URL(`../../${REMEDIATION_DOC}`, import.meta.url);
expect(await Bun.file(abs).exists()).toBe(true);
});

test("returns 2 on a scan error (fail closed)", async () => {
Expand Down
18 changes: 17 additions & 1 deletion tools/orion-ref-gate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ export const CARVEOUT_PATHS: readonly string[] = ["bun.lock"];
*/
export const ALLOWLIST: Readonly<Record<string, string>> = {};

/**
* The in-repo doc stating the boundary rule, cited in the failure hint. Named
* here so the test can assert the file actually exists: a bare string would
* let a docs move silently kill the pointer again — the exact defect this
* hint was repaired for. Wording tracks its "Never name or point at the
* private repo" bullet; update both together. This path also appears in
* `moon.yml` as an input of the `test` task — that declaration is what makes
* moon's cache re-run the assertion when the doc changes, so move both. Note
* a pull_request selects targets by project, so any PR not touching this
* project's own tree does not select this gate at all — including its leak
* scan — and relies on the main/nightly full sweep (see moon.yml).
*/
export const REMEDIATION_DOC = "docs/concepts/self-host-and-managed.md";

/** One scanned line carrying the token. */
export interface Reference {
readonly file: string;
Expand Down Expand Up @@ -154,7 +168,9 @@ export async function runOnce(deps: Deps): Promise<number> {
deps.err(` ${v.file}:${v.line}: ${v.text.trim()}`);
deps.err(
"A public repo must not name, cite, or quote the private internal monorepo. " +
"Refer to it by architectural role instead (see skill://private-repo-boundary).",
'Refer to it by architectural role instead — say "the managed service", or ' +
"describe the core capability directly so it need not be named. " +
`See ${REMEDIATION_DOC}.`,
);
return 1;
}
Expand Down
37 changes: 34 additions & 3 deletions tools/orion-ref-gate/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
# lint/format are whole-repo tasks on the root project (/moon.yml), so this
# leaf has no own bun.lock and never runs its own install.
#
# Compass CI is a single moon-driven `CI` job (.github/workflows/ci.yml runs
# `moon run :ci`), so the `ci` aggregate below is swept automatically.
# Compass CI runs a per-concern matrix, not one job: tools/ci-matrix computes
# the targets and .github/workflows/ci.yml runs `moon run <targets>`, so this
# project's `ci` aggregate is swept only when the matrix selects it.
layer: 'tool'
language: 'typescript'
tags: ['bun', 'ci-group.bun']
Expand All @@ -19,7 +20,37 @@ tasks:
deps: ['install']
inputs: ['*.ts', 'tsconfig.json', '/tsconfig.base.json', 'package.json', '/bun.lock']
test:
inputs: ['*.ts', 'tsconfig.json', '/tsconfig.base.json', 'package.json', '/bun.lock']
# `/docs/concepts/self-host-and-managed.md` is a real input: a test asserts
# the doc cited in the failure hint still exists, so the cache key must
# track it. Without it moon replays a green after the doc is deleted —
# the same silent-pointer-death this gate's hint was repaired for. Scoped
# to the one cited file, not `/docs/**`, so unrelated docs edits don't
# re-run the suite. Keep in sync with `REMEDIATION_DOC` in index.ts.
#
# That declaration governs moon's CACHE, not CI's task selection: on a
# pull_request, tools/ci-matrix selects targets via `moon query projects
# --affected`, which walks the project graph and never consults a
# cross-tree input (see the discriminator note in
# .github/workflows/ci.yml). KNOWN GAP, and it is not docs-specific: ANY
# PR that does not touch this project's own tree fails to select it, since
# the `check` scan's `/**/*` input is cross-tree the same way. A Go-only
# or docs-only PR that ADDS a private-repo reference is therefore not
# gated on that PR; the doc pointer going stale is the mild case. The
# backstop is ci.yml's unconditional push + nightly full sweep, which does
# run the scan to a real verdict. `dependsOn: ['root']` would close the
# PR-time gap — root's source is `.`, so every path marks it affected and
# `--downstream direct` would pull this project in — but for the same
# reason it would run the gate on EVERY PR, since moon edges are
# project-level rather than file-level. sql-migration-gate declines the
# same edge, though its gap is narrower (two root-level configs).
# Tracked as RIG-3381.
inputs:
- '*.ts'
- 'tsconfig.json'
- '/tsconfig.base.json'
- 'package.json'
- '/bun.lock'
- '/docs/concepts/self-host-and-managed.md'
check:
# The boundary gate: scan the whole tracked tree (via git grep) for any
# reference to the private monorepo. Run from the workspace root so the
Expand Down
Loading