@attalabs/vinaya 0.22.0 → 0.24.0
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.
- package/README.md +14 -3
- package/aeg-root/contracts/archivist-tranche-archivist.md +2 -2
- package/aeg-root/contracts/brief-developer.md +1 -0
- package/aeg-root/contracts/developer-reviewer.md +3 -3
- package/aeg-root/contracts/reviewer-archivist.md +3 -3
- package/aeg-root/enforcement.md +26 -20
- package/aeg-root/process.md +8 -4
- package/aeg-root/roles/archivist.md +2 -2
- package/aeg-root/roles/brief-author.md +9 -3
- package/aeg-root/roles/developer.md +63 -31
- package/aeg-root/roles/planner.md +1 -1
- package/aeg-root/roles/principal.md +14 -0
- package/aeg-root/roles/reviewer.md +32 -15
- package/aeg-root/roles/security.md +15 -5
- package/aeg-root/skills/aeg/SKILL.md +9 -5
- package/aeg-root/skills/aeg-roles/SKILL.md +2 -2
- package/aeg-root/skills/brief-authoring/SKILL.md +39 -27
- package/aeg-root/state-machine.md +9 -11
- package/aeg-root/templates/brief-template.md +6 -6
- package/aeg-root/templates/pr-report-template.md +10 -7
- package/aeg-root/tranche-model.md +6 -2
- package/dist/checks/bin/check-body-bare-digits.js +559 -140
- package/dist/checks/bin/check-branch-topology.js +630 -145
- package/dist/checks/bin/check-brief-shape.js +600 -143
- package/dist/checks/bin/check-changeset-coverage.js +942 -162
- package/dist/checks/bin/check-closes-n.js +630 -145
- package/dist/checks/bin/check-coherence.js +641 -148
- package/dist/checks/bin/check-dead-branch-push.js +559 -140
- package/dist/checks/bin/check-dispatch-readiness.js +639 -146
- package/dist/checks/bin/check-doc-coverage-push.js +696 -219
- package/dist/checks/bin/check-doc-coverage.js +696 -219
- package/dist/checks/bin/check-doctrine-no-procedures.js +4800 -0
- package/dist/checks/bin/check-doctrine-portability.js +691 -147
- package/dist/checks/bin/check-evidence-fresh.js +1048 -222
- package/dist/checks/bin/check-exec-bits.js +4937 -0
- package/dist/checks/bin/check-first-push-dispatch.js +630 -145
- package/dist/checks/bin/check-issue-assignment.js +630 -145
- package/dist/checks/bin/check-main-branch-refusal.js +565 -141
- package/dist/checks/bin/check-no-disk-state.js +559 -140
- package/dist/checks/bin/check-pr-report-density.js +4467 -0
- package/dist/checks/bin/check-quoted-command.js +656 -164
- package/dist/checks/bin/check-reader-resolvable-prose.js +652 -163
- package/dist/checks/bin/check-registry-gates.js +602 -145
- package/dist/checks/bin/check-retired-vocabulary.js +652 -163
- package/dist/checks/bin/check-review-gate.js +677 -142
- package/dist/checks/bin/check-single-plan-pr.js +559 -140
- package/dist/checks/bin/check-test-plan.js +560 -141
- package/dist/checks/bin/check-token-collection-wired.js +559 -140
- package/dist/checks/bin/check-token-report.js +559 -140
- package/dist/checks/bin/check-workspace-escape.js +992 -146
- package/dist/index.js +8884 -5627
- package/package.json +1 -1
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/actions.ts +173 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/anchored-region.ts +118 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/archive-task.ts +206 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/baseline-capture.ts +65 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/blast-radius-domains.ts +198 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/branch-topology-gate.ts +85 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-render.ts +462 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-validation.ts +912 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/claude-code-transcript.ts +460 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/coherence-checks.ts +806 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/consumer-enumeration.ts +75 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dead-branch-push-audit.ts +55 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dead-branch-push-guard.ts +77 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/derive-section7.ts +66 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/derive-tranche.ts +94 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/diagram-model.ts +372 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/direct-main-push.ts +39 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dispatch-gate.ts +268 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doc-owners.ts +314 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/build-doc-nav.ts +38 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/docs-coherence.ts +136 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/index.ts +29 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/legacy-anchors.ts +48 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/nav-helpers.ts +17 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/node-route.ts +134 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/parse-doc.ts +43 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/published-prose.ts +306 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/surfaced-manifest.ts +89 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/types.ts +33 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-no-procedures.ts +94 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-portability.ts +293 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-source.ts +23 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/ensure-label.ts +28 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/file-classify.ts +51 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/first-push-dispatch-gate.ts +80 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/gate-audience.ts +171 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/index.ts +323 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/issue-assignment.ts +102 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/issue-validation.ts +746 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/leftover-detection.ts +68 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/local-anchor-coverage.ts +245 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/main-branch-refusal.ts +64 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/manifest-validity.ts +81 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/markdown-table.ts +76 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/metering-io-guard.ts +119 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/milestone-validation.ts +240 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/no-disk-state.ts +50 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-ledger.ts +77 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-registry.ts +105 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-token-report.ts +177 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-tranche.ts +183 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/pr-report-density.ts +116 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/pr-tier.ts +81 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/premise-check.ts +160 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/quoted-command.ts +275 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/reader-resolvable-prose.ts +320 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-checks.ts +255 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-parse.ts +164 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-scaffold.ts +216 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/report-tokens.ts +261 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/retired-vocabulary.ts +163 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/review-gate.ts +378 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/review-status.ts +200 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/single-plan-pr.ts +73 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/state-machine-model.ts +269 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/state-source.ts +14 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/status-block.ts +8 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/sum-ledger.ts +26 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/symbol-collisions.ts +78 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/test-plan-gate.ts +117 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/test-plan-section.ts +65 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/types.ts +174 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/verdict-extraction.ts +199 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/vocabulary-citation.ts +114 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/waiver-label.ts +52 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/workspace-escape.ts +172 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/[root-of-the-server]__02a-3g8._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/1q96_modules_@clerk_nextjs_dist_esm_app-router_client_keyless-creator-reader_0lom2js.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__069-_41._.js → [root-of-the-server]__1pndh3_._.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1fqw88f._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_projects_[name]_tranches_[slug]_05ufo8i._.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{37hnluhzj9bei.js → 0zebsmmk1bvnb.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{267o-tsrnuwnv.js → 1uogpj5w2n5ju.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1hufpuody6vjv.js → 3m1kgax7j2vgs.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
- /package/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/{aeg-core → vinaya/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/aeg-core}/bin/verify-coherence.ts +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{Fmyc42qzLwFcWWHLLNy-G → QY2GhiI47-765D9DHGy1I}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{Fmyc42qzLwFcWWHLLNy-G → QY2GhiI47-765D9DHGy1I}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{Fmyc42qzLwFcWWHLLNy-G → QY2GhiI47-765D9DHGy1I}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who each governance gate under `packages/aeg-core/bin/` is FOR.
|
|
3
|
+
*
|
|
4
|
+
* The problem this closes: this repository holds two parallel worlds — the
|
|
5
|
+
* gates it runs on itself (`packages/aeg-core/bin/*`) and the checks an
|
|
6
|
+
* adopter runs through the published CLI (`apps/cli/src/checks/bin/*`) — and
|
|
7
|
+
* nothing asserted a relationship between them. Membership of the shipped set
|
|
8
|
+
* was defined by ABSENCE from `coreCheckRegistry()`, which means a deliberate
|
|
9
|
+
* exclusion and a forgotten port left exactly the same trace.
|
|
10
|
+
*
|
|
11
|
+
* `reader-resolvable-prose` is the instructive case, and the reason this file
|
|
12
|
+
* exists. That call was made carefully and its reasoning written up well — in
|
|
13
|
+
* a paragraph of prose inside `registry.ts`. It is right, and it is invisible
|
|
14
|
+
* to tooling. A good decision and an unmade decision looked identical, so the
|
|
15
|
+
* next one might simply not get made.
|
|
16
|
+
*
|
|
17
|
+
* So `internal` is a thing you must SAY, with a reason, rather than something
|
|
18
|
+
* you can forget to notice. `gate-audience.test.ts` enumerates the bin
|
|
19
|
+
* directory and fails when a gate is in neither column.
|
|
20
|
+
*
|
|
21
|
+
* **This is deliberately NOT a field on `CheckSpec`.** Adopter-defined checks
|
|
22
|
+
* in `vinaya.config.json` produce that same shape (`lib/config.ts`), so an
|
|
23
|
+
* `audience` field there would push an internal-governance concept into
|
|
24
|
+
* adopter-facing config, where it means nothing and cannot be answered.
|
|
25
|
+
* The question is about THIS repo's own bins, so the declaration lives here.
|
|
26
|
+
*
|
|
27
|
+
* Adding a gate to `bin/` and nothing else is now a failing build, naming the
|
|
28
|
+
* file. That is the whole mechanism; deciding which column a given gate
|
|
29
|
+
* belongs in stays a human judgement, which is the point.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/** A gate that adopters run, and the `coreCheckRegistry()` name it ships
|
|
33
|
+
* under. `ring` mirrors `apps/cli/src/checks/registry.ts`'s `CORE_CHECK_RING`
|
|
34
|
+
* value for that same name — duplicated here, not imported, because
|
|
35
|
+
* `aeg-core` cannot import `apps/cli` (see this file's own module comment on
|
|
36
|
+
* the dependency-cycle constraint `coreCheckRegistry()` runs into). Kept
|
|
37
|
+
* from drifting by `registry-ring-parity.test.ts` (`apps/cli`), which is the
|
|
38
|
+
* only place both sides are in scope at once — same shape as
|
|
39
|
+
* `shipped-bin-audience.test.ts`'s existing `shippedAs` cross-check. This is
|
|
40
|
+
* the "registry-derived fact" `registry-scaffold.ts` reads to place a stub
|
|
41
|
+
* row for an aeg-core-bin G2 candidate that IS registry-backed; a candidate
|
|
42
|
+
* with no entry here gets no stub (see `registry-scaffold.ts`). */
|
|
43
|
+
export type ShippedGate = { shippedAs: string | string[]; ring: 0 | 1 | 2 }
|
|
44
|
+
/** A gate this repo runs on itself, and why it cannot or should not ship. */
|
|
45
|
+
export type InternalGate = { internal: string }
|
|
46
|
+
export type GateAudience = ShippedGate | InternalGate
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Keyed by basename (no extension) of each `packages/aeg-core/bin/*.ts` that
|
|
50
|
+
* is a GATE — something that inspects a repo and passes or fails. Non-gate
|
|
51
|
+
* tooling in the same directory (forge writers, one-shot reporters) is listed
|
|
52
|
+
* in `NON_GATE_BINS` below rather than given a fake audience.
|
|
53
|
+
*/
|
|
54
|
+
export const GATE_AUDIENCE: Record<string, GateAudience> = {
|
|
55
|
+
'check-branch-topology': { shippedAs: 'branch-topology', ring: 0 },
|
|
56
|
+
'check-first-push-dispatch': { shippedAs: 'first-push-dispatch', ring: 0 },
|
|
57
|
+
'check-no-disk-state': { shippedAs: 'no-disk-state', ring: 0 },
|
|
58
|
+
'verify-brief': { shippedAs: 'brief-shape', ring: 0 },
|
|
59
|
+
'verify-coherence': { shippedAs: 'coherence', ring: 0 },
|
|
60
|
+
'verify-dispatch': { shippedAs: 'dispatch-readiness', ring: 0 },
|
|
61
|
+
'verify-docs': { shippedAs: ['doc-coverage', 'doc-coverage-push'], ring: 0 },
|
|
62
|
+
'verify-registry': { shippedAs: 'registry-gates', ring: 0 },
|
|
63
|
+
'verify-review-gate': { shippedAs: 'review-gate', ring: 1 },
|
|
64
|
+
'verify-single-plan-pr': { shippedAs: 'single-plan-pr', ring: 0 },
|
|
65
|
+
'verify-test-plan': { shippedAs: 'test-plan', ring: 1 },
|
|
66
|
+
|
|
67
|
+
'check-direct-main-push': {
|
|
68
|
+
internal:
|
|
69
|
+
'Reaches adopters through `vinaya audit --only=direct-push`, not the check registry: it is a ring-2 sweep over merge history keyed on `GITHUB_SHA`, run by the generated archivist job on push to the default branch. It has no diff to key on, so there is nothing for `vinaya check` to run it against.'
|
|
70
|
+
},
|
|
71
|
+
'check-push-target': {
|
|
72
|
+
internal:
|
|
73
|
+
'A pre-push hook helper: it takes a branch name as `argv[2]` and answers one `gh pr list --head <branch>` question, for a caller that already knows which ref is being pushed. Adopters reach the same question through the registered `dead-branch-push`, which resolves the branch itself when `BRANCH` is unset. Registering this one too would add a second entry answering an identical forge query with a worse interface.'
|
|
74
|
+
},
|
|
75
|
+
'verify-task': {
|
|
76
|
+
internal:
|
|
77
|
+
"A composite that shells this repo's own `typecheck`/`lint`/`test`/`build` scripts by name. Those names are this monorepo's toolchain (bun + turbo + biome), not an adopter's; the shipped equivalent of its intent is `vinaya check --all`, which is portable by construction."
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The other half, and the one the motivating case actually lives in.
|
|
83
|
+
*
|
|
84
|
+
* `reader-resolvable-prose` has no bin under `packages/aeg-core/bin/` at all —
|
|
85
|
+
* its logic is `src/reader-resolvable-prose.ts` and its only executable is
|
|
86
|
+
* `apps/cli/src/checks/bin/check-reader-resolvable-prose.ts`. So the map above
|
|
87
|
+
* would never have seen it, and an earlier revision of this file claimed it as
|
|
88
|
+
* the reason the file exists while leaving it uncovered. Review caught that;
|
|
89
|
+
* this is the fix, not a re-wording.
|
|
90
|
+
*
|
|
91
|
+
* Enumerating the SHIPPED check bins asks the question that case actually
|
|
92
|
+
* poses: here is an executable adopters could run — is it registered, and if
|
|
93
|
+
* not, why not? `coreCheckRegistry()` lives in `apps/cli`, which `aeg-core`
|
|
94
|
+
* cannot import without closing a dependency cycle, so the declaration lives
|
|
95
|
+
* here and `apps/cli`'s own suite does the asserting.
|
|
96
|
+
*
|
|
97
|
+
* `check-reader-resolvable-prose`/`check-retired-vocabulary` (task 7, Issue
|
|
98
|
+
* #56): both used to live here as `internal` — hardcoded monorepo-specific
|
|
99
|
+
* doctrine paths made them unreachable through an adopter's own registry.
|
|
100
|
+
* Both are now config-driven (`vinaya.config.json`'s `proseGates`) and
|
|
101
|
+
* registered in `coreCheckRegistry()` as `reader-resolvable-prose` /
|
|
102
|
+
* `retired-vocabulary`, so neither belongs in this map any more — this repo's
|
|
103
|
+
* own `shipped-bin-audience.test.ts` refuses a bin declared in BOTH places.
|
|
104
|
+
*/
|
|
105
|
+
export const SHIPPED_BIN_AUDIENCE: Record<string, GateAudience> = {}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* `name` -> `ring` for every check registered in `coreCheckRegistry()` whose
|
|
109
|
+
* bin lives under `apps/cli/src/checks/bin/` — the direct analogue of
|
|
110
|
+
* `ShippedGate.ring` above, for the OTHER directory. Mirrors
|
|
111
|
+
* `apps/cli/src/checks/registry.ts`'s `CORE_CHECK_RING` — duplicated, not
|
|
112
|
+
* imported, for the identical dependency-cycle reason `ShippedGate.ring`'s
|
|
113
|
+
* own comment gives: `aeg-core` cannot import `apps/cli`. This is the
|
|
114
|
+
* registry-derived fact `registry-scaffold.ts` reads to place a stub row for
|
|
115
|
+
* an `apps/cli/src/checks/bin/` G2 candidate; a bin whose stripped name has
|
|
116
|
+
* no entry here gets no stub — same no-guess discipline `classify()`
|
|
117
|
+
* already applies to `packages/aeg-core/bin/` candidates via
|
|
118
|
+
* `GATE_AUDIENCE`. Kept from drifting by `shipped-bin-audience.test.ts`
|
|
119
|
+
* (`apps/cli`)'s own ring-parity block, the only place both sides are in
|
|
120
|
+
* scope at once — same shape as this file's `ShippedGate.ring` check.
|
|
121
|
+
*/
|
|
122
|
+
export const CLI_CHECK_RING: Readonly<Record<string, 0 | 1 | 2>> = {
|
|
123
|
+
'brief-shape': 0,
|
|
124
|
+
'pr-report-density': 0,
|
|
125
|
+
'doc-coverage': 0,
|
|
126
|
+
coherence: 0,
|
|
127
|
+
'dispatch-readiness': 0,
|
|
128
|
+
'closes-n': 1,
|
|
129
|
+
'single-plan-pr': 0,
|
|
130
|
+
'test-plan': 1,
|
|
131
|
+
'body-bare-digits': 1,
|
|
132
|
+
'no-disk-state': 0,
|
|
133
|
+
'registry-gates': 0,
|
|
134
|
+
'review-gate': 1,
|
|
135
|
+
'branch-topology': 0,
|
|
136
|
+
'dead-branch-push': 0,
|
|
137
|
+
'first-push-dispatch': 0,
|
|
138
|
+
'doc-coverage-push': 0,
|
|
139
|
+
'issue-assignment': 0,
|
|
140
|
+
'evidence-fresh': 1,
|
|
141
|
+
'reader-resolvable-prose': 0,
|
|
142
|
+
'retired-vocabulary': 0,
|
|
143
|
+
'doctrine-no-procedures': 0,
|
|
144
|
+
'doctrine-portability': 0,
|
|
145
|
+
'workspace-escape': 0,
|
|
146
|
+
'exec-bits': 0,
|
|
147
|
+
'changeset-coverage': 0,
|
|
148
|
+
'quoted-command': 0,
|
|
149
|
+
'main-branch-refusal': 0,
|
|
150
|
+
'token-collection-wired': 0,
|
|
151
|
+
'token-report': 1
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Files in `bin/` that are not gates and therefore have no audience: forge
|
|
156
|
+
* writers and one-shot reporters. Listed explicitly rather than pattern-matched
|
|
157
|
+
* so a NEW file cannot slip through by being named unlike a gate.
|
|
158
|
+
*/
|
|
159
|
+
export const NON_GATE_BINS = [
|
|
160
|
+
'archive-task',
|
|
161
|
+
'assign-task-issue',
|
|
162
|
+
'dead-branch-audit',
|
|
163
|
+
'eval-agent-compliance',
|
|
164
|
+
'open-issue',
|
|
165
|
+
'open-pr',
|
|
166
|
+
'report-tokens'
|
|
167
|
+
] as const
|
|
168
|
+
|
|
169
|
+
export function isShipped(a: GateAudience): a is ShippedGate {
|
|
170
|
+
return 'shippedAs' in a
|
|
171
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
export * from './types'
|
|
2
|
+
export type { StateSource } from './state-source'
|
|
3
|
+
export type { DoctrineContent, DoctrineSource } from './doctrine-source'
|
|
4
|
+
export { CLI_CHECK_RING, GATE_AUDIENCE, NON_GATE_BINS, SHIPPED_BIN_AUDIENCE, isShipped } from './gate-audience'
|
|
5
|
+
export type { GateAudience, InternalGate, ShippedGate } from './gate-audience'
|
|
6
|
+
export { ANCHOR_FIELDS, anchoredRegion, anchoredRegionBounds } from './anchored-region'
|
|
7
|
+
export type { AnchorField } from './anchored-region'
|
|
8
|
+
export { parseRegistry } from './parse-registry'
|
|
9
|
+
export {
|
|
10
|
+
CROSS_CUTTING_CANDIDATES,
|
|
11
|
+
deriveBuiltinCrossCuttingDefaults,
|
|
12
|
+
deriveWorkspacePackageDomains,
|
|
13
|
+
parsePnpmWorkspaceYaml,
|
|
14
|
+
resolveWorkspaceEntry
|
|
15
|
+
} from './blast-radius-domains'
|
|
16
|
+
export { buildConsumersOf, deriveWorkspaceMemberDirs } from './consumer-enumeration'
|
|
17
|
+
export type { PackageManifest } from './consumer-enumeration'
|
|
18
|
+
export { parseTranche } from './parse-tranche'
|
|
19
|
+
export { deriveTranche } from './derive-tranche'
|
|
20
|
+
export { parseLedger, rowFromCells } from './parse-ledger'
|
|
21
|
+
export { sumLedger } from './sum-ledger'
|
|
22
|
+
export { aggregateTaskTokenRows, parseTokenReportEntries, parseTokensLines } from './parse-token-report'
|
|
23
|
+
export type { TokenSourcePr } from './parse-token-report'
|
|
24
|
+
export { deriveReviewStatus, parseDeveloperRoundMarker, renderReviewStatus } from './review-status'
|
|
25
|
+
export type { ReviewStatus, ReviewStatusInput } from './review-status'
|
|
26
|
+
export { formatBreakdown, formatTokenReportRow, formatTokensLine } from './report-tokens'
|
|
27
|
+
export type { TokenReportRowInput, TokensLineInput, TranscriptSummary, UsageComponents } from './report-tokens'
|
|
28
|
+
// The Claude Code collection adapter (`tranche-model.md` §12 layer 2) — one
|
|
29
|
+
// host's way to produce a `TranscriptSummary`, exported beside the portable
|
|
30
|
+
// renderers it feeds, never as a requirement of the contract.
|
|
31
|
+
export {
|
|
32
|
+
isTokenCollectionWiringBroken,
|
|
33
|
+
resolveMeteringCapability,
|
|
34
|
+
summarizeTranscript
|
|
35
|
+
} from './claude-code-transcript'
|
|
36
|
+
export type { MeteringCapability, MeteringCapabilityDeps, MeteringIncapableReason } from './claude-code-transcript'
|
|
37
|
+
// The hardened deps every real caller of `resolveMeteringCapability` should
|
|
38
|
+
// build from (`#313`) — a sibling module, not part of the pure adapter above.
|
|
39
|
+
export { hardenedMeteringDeps, isTrustedMeteringStat } from './metering-io-guard'
|
|
40
|
+
export { declarationsIn, findCollisions } from './symbol-collisions'
|
|
41
|
+
export type { SymbolCollision, SymbolDeclaration } from './symbol-collisions'
|
|
42
|
+
export { isCodeFile, isDocFile, isSpecFile } from './file-classify'
|
|
43
|
+
export { hasStatusBlock } from './status-block'
|
|
44
|
+
export {
|
|
45
|
+
classifyDocOwnersManifest,
|
|
46
|
+
DOC_OWNERS_PATH,
|
|
47
|
+
evaluateC5,
|
|
48
|
+
globToRegex,
|
|
49
|
+
isMechanicallyNeutralDiff,
|
|
50
|
+
isUrlPointer,
|
|
51
|
+
parseDocOwners,
|
|
52
|
+
pointerToPath,
|
|
53
|
+
readDocAcks,
|
|
54
|
+
readDocNeutrals
|
|
55
|
+
} from './doc-owners'
|
|
56
|
+
export type { C5Result, DocAck, DocNeutral, DocOwnersBinding, DocOwnersManifestState } from './doc-owners'
|
|
57
|
+
export {
|
|
58
|
+
isPrincipal,
|
|
59
|
+
isWaiverLabelActorVerified,
|
|
60
|
+
PRINCIPAL_ALLOWLIST,
|
|
61
|
+
WAIVER_LABEL,
|
|
62
|
+
WAIVER_LABEL_REVIEW
|
|
63
|
+
} from './waiver-label'
|
|
64
|
+
export { deriveSection7, globsOverlap } from './derive-section7'
|
|
65
|
+
export type { Section7Match } from './derive-section7'
|
|
66
|
+
export { checkManifestValidity, parseNoDocRules } from './manifest-validity'
|
|
67
|
+
export type { NoDocRule } from './manifest-validity'
|
|
68
|
+
export { evaluateVocabularyCitation } from './vocabulary-citation'
|
|
69
|
+
export type {
|
|
70
|
+
VocabularyCheckResult,
|
|
71
|
+
VocabularyFinding,
|
|
72
|
+
VocabularyHit,
|
|
73
|
+
VocabularyPattern
|
|
74
|
+
} from './vocabulary-citation'
|
|
75
|
+
export { deriveTierFromDiff, overrideActive, readTierFromPrBody, TIER_FIELD } from './pr-tier'
|
|
76
|
+
export {
|
|
77
|
+
checkAutonomyClause,
|
|
78
|
+
checkBriefSections,
|
|
79
|
+
checkClosesN as checkBriefClosesN,
|
|
80
|
+
checkCommandsCarryOutput,
|
|
81
|
+
checkConsumerTests,
|
|
82
|
+
checkDefeatCases,
|
|
83
|
+
checkDocUpdateList,
|
|
84
|
+
checkForField,
|
|
85
|
+
checkForgeTitle,
|
|
86
|
+
checkNoAgentBoxes,
|
|
87
|
+
checkNoUnpinnedCodeClaims,
|
|
88
|
+
checkPlanPrNoCloses,
|
|
89
|
+
checkPremiseCoverage,
|
|
90
|
+
checkPrincipalPlaceholder,
|
|
91
|
+
checkProjectField,
|
|
92
|
+
checkStopConditions,
|
|
93
|
+
checkSurfaceMap,
|
|
94
|
+
checkTestPlan,
|
|
95
|
+
checkTestPlanExclusivity,
|
|
96
|
+
checkTierField,
|
|
97
|
+
checkWorktreeStep0,
|
|
98
|
+
AGENT_BOXES_REFUSED_SINCE_PR,
|
|
99
|
+
BRIEF_RULES_SINCE_PR,
|
|
100
|
+
COMMAND_WORDS,
|
|
101
|
+
COMMIT_TYPE_STYLE,
|
|
102
|
+
COMMIT_TYPES,
|
|
103
|
+
extractFencedBlocks,
|
|
104
|
+
headerRegion,
|
|
105
|
+
inferBranchFromBody,
|
|
106
|
+
isBriefShaped,
|
|
107
|
+
isGrandfatherableBriefRuleError,
|
|
108
|
+
isTaskBranch,
|
|
109
|
+
partitionBriefErrorsByRollout
|
|
110
|
+
} from './brief-validation'
|
|
111
|
+
export type { BriefSectionResult, BriefSectionsOptions, FencedBlock } from './brief-validation'
|
|
112
|
+
export { checkDoctrineNoProcedures } from './doctrine-no-procedures'
|
|
113
|
+
export type { DoctrineFile, DoctrineProcedureFinding } from './doctrine-no-procedures'
|
|
114
|
+
export { checkPrReportDensity, checkScopeDensity, checkSummaryDensity } from './pr-report-density'
|
|
115
|
+
export type { DensityResult } from './pr-report-density'
|
|
116
|
+
export {
|
|
117
|
+
checkA1,
|
|
118
|
+
checkA2,
|
|
119
|
+
checkA3,
|
|
120
|
+
checkClosesN,
|
|
121
|
+
checkD1,
|
|
122
|
+
checkL1,
|
|
123
|
+
checkL2,
|
|
124
|
+
checkL3,
|
|
125
|
+
checkL4,
|
|
126
|
+
checkL5,
|
|
127
|
+
checkR1,
|
|
128
|
+
checkT1,
|
|
129
|
+
checkT2,
|
|
130
|
+
checkT3,
|
|
131
|
+
COHERENCE_ENFORCED_FROM,
|
|
132
|
+
extractClosesReferences,
|
|
133
|
+
isGrandfathered,
|
|
134
|
+
R1_GRANDFATHERED_ISSUES,
|
|
135
|
+
scopeT2ToPlanPr
|
|
136
|
+
} from './coherence-checks'
|
|
137
|
+
export type { CheckFailure, CheckResult, ForgeIssue, TrancheFile, TaskEntry } from './coherence-checks'
|
|
138
|
+
export {
|
|
139
|
+
buildProvenanceBlock,
|
|
140
|
+
extractIssue,
|
|
141
|
+
hasProvenance,
|
|
142
|
+
isEligibleForProvenance,
|
|
143
|
+
taskRefFromBranch
|
|
144
|
+
} from './archive-task'
|
|
145
|
+
export type { MergedPrFacts } from './archive-task'
|
|
146
|
+
export { extractCodeReviewVerdict, extractSecurityReviewVerdict } from './verdict-extraction'
|
|
147
|
+
export type { VerdictExtraction } from './verdict-extraction'
|
|
148
|
+
export {
|
|
149
|
+
CHANGESET_RELEASE_BRANCH,
|
|
150
|
+
checkReviewGate,
|
|
151
|
+
DEFAULT_RELEASE_ACTOR,
|
|
152
|
+
isChangesetsReleasePr,
|
|
153
|
+
isReviewGateExemptBranch
|
|
154
|
+
} from './review-gate'
|
|
155
|
+
export type { ReviewGateComment, ReviewGateInput, ReviewGateResult, ReviewGateVerdict } from './review-gate'
|
|
156
|
+
export {
|
|
157
|
+
checkBlastRadiusScope,
|
|
158
|
+
checkConflictCompleteness,
|
|
159
|
+
checkIssueRationale,
|
|
160
|
+
checkIssueType,
|
|
161
|
+
checkNoBriefContent,
|
|
162
|
+
checkProjectsRegistered,
|
|
163
|
+
checkRationaleNamesDocs,
|
|
164
|
+
declaredProjects,
|
|
165
|
+
isTaskIssueLabelSet
|
|
166
|
+
} from './issue-validation'
|
|
167
|
+
export type { IssueSectionResult, ProjectPath, TaskIssueFacts } from './issue-validation'
|
|
168
|
+
export { findHeadingLine, findTable, rowToRecord } from './markdown-table'
|
|
169
|
+
export type { ParsedTable, TableRow } from './markdown-table'
|
|
170
|
+
export { deriveDiagramModel } from './diagram-model'
|
|
171
|
+
export type {
|
|
172
|
+
DiagramConfig,
|
|
173
|
+
DiagramEdge,
|
|
174
|
+
DiagramFinding,
|
|
175
|
+
DiagramModel,
|
|
176
|
+
DiagramNode,
|
|
177
|
+
DiagramNodeKind,
|
|
178
|
+
RenderState
|
|
179
|
+
} from './diagram-model'
|
|
180
|
+
export { parseEnforcementRegistry } from './registry-parse'
|
|
181
|
+
export type { GateRing, GateRow } from './registry-parse'
|
|
182
|
+
export { checkG1, checkG2, checkG3, checkG4, checkG5, checkG6 } from './registry-checks'
|
|
183
|
+
export type { RegistryCheckResult, RegistryCheckStatus, RegistryFinding } from './registry-checks'
|
|
184
|
+
export { applyScaffoldPlan, computeScaffoldPlan, PLACEHOLDER } from './registry-scaffold'
|
|
185
|
+
export type { ScaffoldPlan, ScaffoldSkip, ScaffoldStub } from './registry-scaffold'
|
|
186
|
+
export { ACTIONS, CROSSING_KEYWORDS } from './actions'
|
|
187
|
+
export type { Action, ActionCrossing } from './actions'
|
|
188
|
+
export {
|
|
189
|
+
DERIVABLE_STATUSES,
|
|
190
|
+
DERIVATION_RULES,
|
|
191
|
+
DERIVED_STATUSES,
|
|
192
|
+
deriveStatusFromModel,
|
|
193
|
+
FORGE_FACT_INPUTS
|
|
194
|
+
} from './state-machine-model'
|
|
195
|
+
export type { DerivationRule, ForgeFactInput } from './state-machine-model'
|
|
196
|
+
export { checkPremises, parsePremiseBlock } from './premise-check'
|
|
197
|
+
export type { PremiseAssertion, PremiseCheckResult } from './premise-check'
|
|
198
|
+
export { classifyLeftover } from './leftover-detection'
|
|
199
|
+
export type { LeftoverInput, LeftoverResult, LeftoverVerdict } from './leftover-detection'
|
|
200
|
+
export { checkDeadBranchPush } from './dead-branch-push-guard'
|
|
201
|
+
export type {
|
|
202
|
+
DeadBranchPushInput,
|
|
203
|
+
DeadBranchPushResult,
|
|
204
|
+
DeadBranchPushVerdict,
|
|
205
|
+
PrStateFact
|
|
206
|
+
} from './dead-branch-push-guard'
|
|
207
|
+
export { captureBaseline, compareToBaseline } from './baseline-capture'
|
|
208
|
+
export type { BaselineComparison, BaselineEntry, BaselineToolComparison } from './baseline-capture'
|
|
209
|
+
export { checkDoctrinePortability } from './doctrine-portability'
|
|
210
|
+
export type { PortabilityFinding, PortabilitySourceFile } from './doctrine-portability'
|
|
211
|
+
export {
|
|
212
|
+
checkReaderResolvableProse,
|
|
213
|
+
checkUndefinedVocabulary,
|
|
214
|
+
checkUnresolvableReferences,
|
|
215
|
+
classifyProseFile,
|
|
216
|
+
legacySlugPattern,
|
|
217
|
+
parseGlossaryTerms,
|
|
218
|
+
stripNonProse
|
|
219
|
+
} from './reader-resolvable-prose'
|
|
220
|
+
export type { ProseFileClass, ProseFinding, ProseSourceFile } from './reader-resolvable-prose'
|
|
221
|
+
export {
|
|
222
|
+
checkQuotedCommandStaleness,
|
|
223
|
+
evaluateCitedQuotes,
|
|
224
|
+
findCitedQuotes,
|
|
225
|
+
isValidCitedFilePath
|
|
226
|
+
} from './quoted-command'
|
|
227
|
+
export type { CitedQuote, QuotedCommandFinding, QuotedCommandSourceFile } from './quoted-command'
|
|
228
|
+
export {
|
|
229
|
+
PATTERN_EXEMPT,
|
|
230
|
+
RETIRED_EXEMPT_SUBSTRINGS,
|
|
231
|
+
RETIRED_PATTERNS,
|
|
232
|
+
scanRetiredVocabulary
|
|
233
|
+
} from './retired-vocabulary'
|
|
234
|
+
export type { VocabFinding, VocabSourceFile } from './retired-vocabulary'
|
|
235
|
+
export { checkLocalAnchorCoverage } from './local-anchor-coverage'
|
|
236
|
+
export type {
|
|
237
|
+
AnchorCoverageFinding,
|
|
238
|
+
AnchorCoverageScope,
|
|
239
|
+
AnchorSourceFile,
|
|
240
|
+
LocalAnchorCoverageOptions,
|
|
241
|
+
LocalAnchorCoverageResult
|
|
242
|
+
} from './local-anchor-coverage'
|
|
243
|
+
export { checkDispatchReadiness } from './dispatch-gate'
|
|
244
|
+
export type {
|
|
245
|
+
DispatchConflictsWithFact,
|
|
246
|
+
DispatchDependsOnFact,
|
|
247
|
+
DispatchEdgeFact,
|
|
248
|
+
DispatchGateInput,
|
|
249
|
+
DispatchIssueFact,
|
|
250
|
+
DispatchPriorTrancheFact,
|
|
251
|
+
DispatchPriorTaskFact,
|
|
252
|
+
DispatchResult
|
|
253
|
+
} from './dispatch-gate'
|
|
254
|
+
export { checkSinglePlanPr, trancheSlugFromTopologyPath, touchesAnyTopology } from './single-plan-pr'
|
|
255
|
+
export type { OpenPrFiles } from './single-plan-pr'
|
|
256
|
+
export { isNewDiskStateFile } from './no-disk-state'
|
|
257
|
+
export type { DiskStateFileStatus } from './no-disk-state'
|
|
258
|
+
export { checkDirectMainPush } from './direct-main-push'
|
|
259
|
+
export type { DirectMainPushFact, DirectMainPushResult } from './direct-main-push'
|
|
260
|
+
export { checkMainBranchRefusal } from './main-branch-refusal'
|
|
261
|
+
export type { MainBranchRefusalFinding, MainBranchRefusalReason } from './main-branch-refusal'
|
|
262
|
+
export { ensureLabelExists, LABEL_COLOR } from './ensure-label'
|
|
263
|
+
export type { LabelExistenceIo } from './ensure-label'
|
|
264
|
+
export { findDeadBranchPushes } from './dead-branch-push-audit'
|
|
265
|
+
export type { DeadBranchFact, DeadBranchPush } from './dead-branch-push-audit'
|
|
266
|
+
export { checkBranchTopology, taskBranchTopologyFields } from './branch-topology-gate'
|
|
267
|
+
export type { BranchTopologyInput, BranchTopologyResult, BranchTopologyVerdict } from './branch-topology-gate'
|
|
268
|
+
export { checkFirstPushDispatchGate, parseTaskBranch } from './first-push-dispatch-gate'
|
|
269
|
+
export type {
|
|
270
|
+
DispatchReadinessFact,
|
|
271
|
+
FirstPushDispatchGateInput,
|
|
272
|
+
FirstPushDispatchGateResult,
|
|
273
|
+
FirstPushDispatchGateVerdict
|
|
274
|
+
} from './first-push-dispatch-gate'
|
|
275
|
+
export { decideIssueAssignment } from './issue-assignment'
|
|
276
|
+
export type { IssueAssignmentDecision, IssueAssignmentInput } from './issue-assignment'
|
|
277
|
+
export { locateTestPlanSection } from './test-plan-section'
|
|
278
|
+
export type { TestPlanSection } from './test-plan-section'
|
|
279
|
+
export { evaluateTestPlanGate } from './test-plan-gate'
|
|
280
|
+
export type { TestPlanGateResult, TestPlanGateVerdict } from './test-plan-gate'
|
|
281
|
+
export {
|
|
282
|
+
AEG_BLOCKED_LABEL,
|
|
283
|
+
buildBranchName,
|
|
284
|
+
fetchForgeFacts,
|
|
285
|
+
fetchForgeTasksByLabel,
|
|
286
|
+
fetchOpenIssuesByLabel,
|
|
287
|
+
fetchTaskIssueRefs,
|
|
288
|
+
findTrancheSlug,
|
|
289
|
+
hasLabel,
|
|
290
|
+
trancheLabel,
|
|
291
|
+
trancheSlugLengthError,
|
|
292
|
+
trancheSlugOf,
|
|
293
|
+
LABEL_MAX_LENGTH,
|
|
294
|
+
LABEL_NAMESPACE,
|
|
295
|
+
LABELS,
|
|
296
|
+
label,
|
|
297
|
+
mapForgeFacts,
|
|
298
|
+
matchesLabel,
|
|
299
|
+
projectsFromBody
|
|
300
|
+
} from '@attalabs/aeg-forge-state'
|
|
301
|
+
export type { Label, LabelCategory, LabelForm, LabelKey } from '@attalabs/aeg-forge-state'
|
|
302
|
+
export type {
|
|
303
|
+
FetchForgeFactsInput,
|
|
304
|
+
ForgeFactsSnapshot,
|
|
305
|
+
PrRef,
|
|
306
|
+
RawTaskFacts,
|
|
307
|
+
TaskIssueRef,
|
|
308
|
+
TaskRef
|
|
309
|
+
} from '@attalabs/aeg-types'
|
|
310
|
+
export { checkAdoptable, checkMilestoneShape, releaseFieldFromBody } from './milestone-validation'
|
|
311
|
+
export type {
|
|
312
|
+
AdoptFacts,
|
|
313
|
+
AdoptResult,
|
|
314
|
+
AdoptSlugFacts,
|
|
315
|
+
AdoptTargetFacts,
|
|
316
|
+
MilestoneIntent,
|
|
317
|
+
MilestoneShapeResult,
|
|
318
|
+
ReleaseField
|
|
319
|
+
} from './milestone-validation'
|
|
320
|
+
export { findWorkspaceEscapes } from './workspace-escape'
|
|
321
|
+
export type { WorkspaceEscapeFinding, WorkspaceEscapeReason, WorkspaceEscapeSourceFile } from './workspace-escape'
|
|
322
|
+
export { parseRationaleFields, renderBrief } from './brief-render'
|
|
323
|
+
export type { BriefFacts, RationaleFieldKey, RenderResult, SurfaceFileFact } from './brief-render'
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { parseTaskBranch } from './first-push-dispatch-gate'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* First-push Issue self-assignment (aeg-governance-hardening task 33, #401).
|
|
5
|
+
* Pure — no `fs`, no `gh`/`git` shell-outs. The CLI shim
|
|
6
|
+
* (`bin/assign-task-issue.ts`, wired into `.husky/pre-push`) gathers the
|
|
7
|
+
* facts — does the remote ref already exist, which Issue does the topology
|
|
8
|
+
* row name, who is currently assigned, who is the authenticated pusher —
|
|
9
|
+
* and this evaluator decides whether to assign.
|
|
10
|
+
*
|
|
11
|
+
* Produces the signal Studio's dispatch-visibility chip (task 26, #368)
|
|
12
|
+
* renders: `facts.assigned = assigneesCount > 0`. Assignment had never been
|
|
13
|
+
* mechanized anywhere — it happened only when the Principal remembered to
|
|
14
|
+
* assign by hand, so a genuinely in-flight task (task 28, #372: two real
|
|
15
|
+
* commits pushed) looked identical to an untouched one. The task branch's
|
|
16
|
+
* FIRST real push is the earliest genuine "in flight" evidence (assigning
|
|
17
|
+
* at brief-authoring time would reintroduce the false positive task 26 was
|
|
18
|
+
* built to avoid), so that is the moment this fires.
|
|
19
|
+
*
|
|
20
|
+
* Every guard skips rather than errors — this is a visibility nicety, never
|
|
21
|
+
* a gate. In particular: `assignees`/`login` arriving as `null` (a failed
|
|
22
|
+
* `gh` call) means "no signal", and no-signal means no action — never a
|
|
23
|
+
* guess, never a block.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export type IssueAssignmentInput = {
|
|
27
|
+
/** The branch being pushed. */
|
|
28
|
+
branch: string
|
|
29
|
+
/**
|
|
30
|
+
* Whether the remote ref already exists — from the pre-push stdin's
|
|
31
|
+
* remote-sha (all zeros = the ref is being created by this push, i.e.
|
|
32
|
+
* genuinely the first push). A force-push to an existing branch keeps a
|
|
33
|
+
* non-zero remote-sha and therefore never re-triggers; deleting and
|
|
34
|
+
* recreating the remote branch re-presents a zero sha, which the
|
|
35
|
+
* already-assigned no-op below absorbs.
|
|
36
|
+
*/
|
|
37
|
+
remoteRefExists: boolean
|
|
38
|
+
/** The topology row's Issue number, or `null` when the row or its Issue cell could not be resolved. */
|
|
39
|
+
issue: number | null
|
|
40
|
+
/** Current assignee logins on the Issue, or `null` when the fetch failed. */
|
|
41
|
+
assignees: string[] | null
|
|
42
|
+
/** The authenticated `gh` login — the actual pusher — or `null` when unresolvable. Never a hardcoded fallback. */
|
|
43
|
+
login: string | null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type IssueAssignmentDecision =
|
|
47
|
+
| { action: 'assign'; issue: number; login: string; reason: string }
|
|
48
|
+
| { action: 'skip'; reason: string }
|
|
49
|
+
|
|
50
|
+
export function decideIssueAssignment(input: IssueAssignmentInput): IssueAssignmentDecision {
|
|
51
|
+
const { branch, remoteRefExists, issue, assignees, login } = input
|
|
52
|
+
|
|
53
|
+
if (parseTaskBranch(branch) === null) {
|
|
54
|
+
return {
|
|
55
|
+
action: 'skip',
|
|
56
|
+
reason: `Branch \`${branch}\` is not a task/<tranche>/<n> branch — Issue self-assignment only applies to task branches.`
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (remoteRefExists) {
|
|
61
|
+
return {
|
|
62
|
+
action: 'skip',
|
|
63
|
+
reason: `Branch \`${branch}\` already exists on the remote — not its first push, nothing to assign.`
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (issue === null) {
|
|
68
|
+
return {
|
|
69
|
+
action: 'skip',
|
|
70
|
+
reason: `No Issue resolved for \`${branch}\` from its topology row — skipping self-assignment (the gate owns refusing an unplanned branch).`
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (assignees === null) {
|
|
75
|
+
return {
|
|
76
|
+
action: 'skip',
|
|
77
|
+
reason: `Could not read Issue #${issue}'s current assignees — skipping rather than risking a double-assign (fail-open, never a guess).`
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (assignees.length > 0) {
|
|
82
|
+
return {
|
|
83
|
+
action: 'skip',
|
|
84
|
+
reason: `Issue #${issue} is already assigned (${assignees.join(', ')}) — no-op.`
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (login === null) {
|
|
89
|
+
return {
|
|
90
|
+
action: 'skip',
|
|
91
|
+
reason:
|
|
92
|
+
'Could not resolve the authenticated `gh` login — never assigning anyone other than the actual pusher, so skipping.'
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
action: 'assign',
|
|
98
|
+
issue,
|
|
99
|
+
login,
|
|
100
|
+
reason: `First push of \`${branch}\` — assigning Issue #${issue} to @${login} (the authenticated pusher).`
|
|
101
|
+
}
|
|
102
|
+
}
|