@davidvornholt/standards 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/cli.ts +17 -2
package/README.md CHANGED
@@ -16,7 +16,7 @@ standards github --apply
16
16
 
17
17
  `dependabot --write` regenerates the composed `.github/dependabot.yml` from the canonical `.github/dependabot.base.yml` and the optional repo-owned `.github/dependabot.local.yml`; `init` and `sync` do the same automatically. `dependabot --check` verifies the generated file still matches its sources, and `doctor`/`check` include the same verification. The overlay is deliberately lean and additive only: new update blocks for repo-specific ecosystems, top-level private registry definitions, and `ignore` or `registries` entries appended by repeating a canonical block's normalized target. Matching blocks cannot add labels, groups, cooldowns, pull-request limits, or other policy.
18
18
 
19
- `github --check` compares the live GitHub repository (merge settings and rulesets) against the merged declaration in `.github/settings.json` + `.github/settings.local.json`; `github --apply` converges the live repository to exactly the declared state. `check` runs the same comparison whenever `.github/settings.json` is present, and fails closed: declared state the token cannot see fails the gate with a message naming the token fix instead of passing unverified. `--apply` re-diffs the PATCH response, so a setting GitHub accepts with HTTP 200 but silently ignores (plan-unavailable features) is a reported failure, not a false success. A repository whose GitHub plan cannot enforce rulesets can declare that in the seam (see `rulesetEnforcement` below); both commands then skip rulesets and plan-gated repository settings, converge the rest, and print an unprotected-branch notice on every run.
19
+ `github --check` compares the live GitHub repository (merge settings and rulesets) against the merged declaration in `.github/settings.json` + `.github/settings.local.json`; `github --apply` converges the live repository to exactly the declared state. `check` runs the same comparison whenever `.github/settings.json` is present, and fails closed: declared state the token cannot see fails the gate with a message naming the token fix instead of passing unverified. The canonical workflow sets `STANDARDS_SKIP_GITHUB_CHECK=true` only in its unprivileged quality step because its isolated `github-settings` job runs the live comparison with the admin-read token; this is a workflow-internal integration seam, not a general way to disable the local gate. The CLI prints an explicit diagnostic whenever that exact value skips either `check`'s live phase or `github --check`; `github --apply` is never skipped. `--apply` re-diffs the PATCH response, so a setting GitHub accepts with HTTP 200 but silently ignores (plan-unavailable features) is a reported failure, not a false success. A repository whose GitHub plan cannot enforce rulesets can declare that in the seam (see `rulesetEnforcement` below); both commands then skip rulesets and plan-gated repository settings, converge the rest, and print an unprotected-branch notice on every run.
20
20
 
21
21
  `structure` enforces the canonical monorepo structure contract: workspace scripts (`check-types`, `lint`, `lint:fix`, `test`), root gate scripts, filtered Turbo convenience aliases, internal `0.0.0`/`workspace:*` versioning, package `exports`, shared tsconfig inheritance, and browser a11y wiring. Only a workspace containing an explicit `*.a11y.ts` suite must provide a `test:a11y` script and direct `@axe-core/playwright` and `@playwright/test` dependencies. `check` includes `structure`, so these rules gate every consumer PR.
22
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidvornholt/standards",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Bootstrap, synchronize, and validate davidvornholt/standards consumers",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.ts CHANGED
@@ -54,6 +54,7 @@ const DEFAULT_UPSTREAM = 'github:davidvornholt/standards';
54
54
  const HASH_PREVIEW_LENGTH = 12;
55
55
 
56
56
  const GITHUB_PREFIX = 'github:';
57
+ const SKIP_GITHUB_CHECK_ENV = 'STANDARDS_SKIP_GITHUB_CHECK';
57
58
 
58
59
  // Never mirrored, even under a managed directory path: build output, VCS
59
60
  // metadata, and installed dependencies would otherwise pollute the lock when
@@ -964,13 +965,27 @@ const runCheckCommand = async (consumer: string): Promise<boolean> => {
964
965
  // closed: once .github/settings.json exists, an unreachable API or an
965
966
  // unreadable origin is a failure, not a skip.
966
967
  const githubIsConverged = existsSync(join(consumer, CANONICAL_SETTINGS_FILE))
967
- ? await runGithubCheck(consumer)
968
+ ? await runGithubCheckGate(consumer)
968
969
  : true;
969
970
  return (
970
971
  driftIsClean && integrationIsValid && structureIsValid && githubIsConverged
971
972
  );
972
973
  };
973
974
 
975
+ // The canonical workflow sets this only for its unprivileged quality job,
976
+ // where a separate isolated job runs the same live check with the admin-read
977
+ // token. Absent that exact workflow seam, local and explicit checks remain
978
+ // fail-closed.
979
+ const runGithubCheckGate = (consumer: string): Promise<boolean> => {
980
+ if (process.env[SKIP_GITHUB_CHECK_ENV] === 'true') {
981
+ console.log(
982
+ `standards github: live settings check skipped because ${SKIP_GITHUB_CHECK_ENV}=true; the canonical workflow's isolated github-settings job must own this check`,
983
+ );
984
+ return Promise.resolve(true);
985
+ }
986
+ return runGithubCheck(consumer);
987
+ };
988
+
974
989
  // Consumer-owned sync policy, checked in next to the canonical (read-only)
975
990
  // standards-sync workflow it configures — versioned and reviewable, unlike
976
991
  // repository Actions variables. All fields are optional; a missing file means
@@ -1116,7 +1131,7 @@ const runGateCommand = (
1116
1131
  if (command === 'structure') {
1117
1132
  return runStructure(consumer, profile);
1118
1133
  }
1119
- return apply ? runGithubApply(consumer) : runGithubCheck(consumer);
1134
+ return apply ? runGithubApply(consumer) : runGithubCheckGate(consumer);
1120
1135
  };
1121
1136
 
1122
1137
  const main = async (): Promise<void> => {