@mrciphersmith/keryx 0.2.75 → 0.2.77
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 +15 -10
- package/dist/cli.js +11809 -9037
- package/dist/proxy-worker.js +12 -12
- package/package.json +1 -1
- package/src/gdgraph/build.ts +12 -0
- package/src/gdgraph/query.ts +51 -1
- package/src/gdgraph/types.ts +77 -0
- package/src/gdgraph/wiki-layer-no-git.test.ts +73 -0
- package/src/gdgraph/wiki-layer.test.ts +211 -0
- package/src/gdgraph/wiki-layer.ts +213 -0
- package/src/gdskills/bundled/rules/core/api-contracts.mdc +6 -4
- package/src/gdskills/bundled/rules/core/model-selection.mdc +4 -5
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.codex.md +4 -38
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.cursor.md +4 -38
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.md +4 -38
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.opencode.md +4 -38
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.zed.md +4 -38
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.codex.md +1 -3
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.cursor.md +1 -3
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +1 -3
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.codex.md +35 -34
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.cursor.md +35 -34
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +35 -34
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.opencode.md +35 -34
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.zed.md +35 -34
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/input-contract.schema.json +1 -1
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.codex.md +2 -4
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.cursor.md +2 -4
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +2 -4
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.opencode.md +2 -4
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.zed.md +2 -4
- package/src/gdskills/bundled/skills/planning/autodoc-orchestrator/SKILL.md +10 -6
- package/src/gdskills/bundled/skills/planning/interview/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/interview/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/interview/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/platform/agent-entrypoint-distiller/SKILL.md +4 -0
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +1 -2
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +1 -2
- package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +4 -0
- package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +4 -0
- package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +4 -0
- package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +1 -2
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +108 -23
- package/src/gdskills/bundled/skills/review/review-orchestrator/review-context.schema.json +175 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +7 -0
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +2 -3
- package/src/gdskills/bundled/skills/review/review-style/SKILL.md +2 -3
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +5 -0
- package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +1 -2
- package/src/gdskills/contracts/review-finding.schema.json +4 -0
|
@@ -534,10 +534,8 @@ second copy of a schema is how that happens.
|
|
|
534
534
|
9. **DO** verify your work before reporting.
|
|
535
535
|
10. **DO** make `STATUS: <TOKEN>` the first line of your final message, and put no
|
|
536
536
|
JSON in the response body. The full JSON result is the file Phase 6.1 writes
|
|
537
|
-
and records.
|
|
538
|
-
|
|
539
|
-
Results`, and `parseChildResult`, the production function that throws on any
|
|
540
|
-
first line that is not a canonical STATUS token.)
|
|
537
|
+
and records. `parseChildResult` throws on any first line that is not a
|
|
538
|
+
canonical STATUS token.
|
|
541
539
|
|
|
542
540
|
---
|
|
543
541
|
|
|
@@ -534,10 +534,8 @@ second copy of a schema is how that happens.
|
|
|
534
534
|
9. **DO** verify your work before reporting.
|
|
535
535
|
10. **DO** make `STATUS: <TOKEN>` the first line of your final message, and put no
|
|
536
536
|
JSON in the response body. The full JSON result is the file Phase 6.1 writes
|
|
537
|
-
and records.
|
|
538
|
-
|
|
539
|
-
Results`, and `parseChildResult`, the production function that throws on any
|
|
540
|
-
first line that is not a canonical STATUS token.)
|
|
537
|
+
and records. `parseChildResult` throws on any first line that is not a
|
|
538
|
+
canonical STATUS token.
|
|
541
539
|
|
|
542
540
|
---
|
|
543
541
|
|
|
@@ -3,13 +3,17 @@ name: autodoc-orchestrator
|
|
|
3
3
|
description: >
|
|
4
4
|
Autonomous reverse-engineering documentation pipeline — scans an existing codebase
|
|
5
5
|
and produces comprehensive developer documentation without user involvement after initial setup.
|
|
6
|
-
Use when
|
|
7
|
-
|
|
8
|
-
"сгенерируй документацию проекта", "задокументируй кодовую базу",
|
|
9
|
-
"автодок", "autodoc".
|
|
10
|
-
Trigger on: user provides a repo path, asks to document existing code, wants
|
|
11
|
-
onboarding docs, API reference, or architecture overview generated automatically.
|
|
6
|
+
Use when the user provides a repo path, asks to document existing code, or wants
|
|
7
|
+
onboarding docs, an API reference, or an architecture overview generated automatically.
|
|
12
8
|
NOT for: writing new PRDs or planning new features (use gproject-orchestrator).
|
|
9
|
+
triggers:
|
|
10
|
+
- "autodoc"
|
|
11
|
+
- "автодок"
|
|
12
|
+
- "document this codebase"
|
|
13
|
+
- "generate docs for my project"
|
|
14
|
+
- "reverse engineer documentation"
|
|
15
|
+
- "задокументируй кодовую базу"
|
|
16
|
+
- "сгенерируй документацию проекта"
|
|
13
17
|
metadata:
|
|
14
18
|
version: 1.0.0
|
|
15
19
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interview
|
|
3
|
-
description: "Use
|
|
3
|
+
description: "Use to clarify implementation-specific ambiguities AFTER context has already been collected and the goal is known — the questions that sharpen a plan, not the ones that scope the request. This is the `implement`-intent interview job-orchestrator runs at 0.3. To pin down a vague request before any context is gathered, use `interviewer` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "/interview"
|
|
6
6
|
- "Interview"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interview
|
|
3
|
-
description: "Use
|
|
3
|
+
description: "Use to clarify implementation-specific ambiguities AFTER context has already been collected and the goal is known — the questions that sharpen a plan, not the ones that scope the request. This is the `implement`-intent interview job-orchestrator runs at 0.3. To pin down a vague request before any context is gathered, use `interviewer` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "/interview"
|
|
6
6
|
- "Interview"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interview
|
|
3
|
-
description: "Use
|
|
3
|
+
description: "Use to clarify implementation-specific ambiguities AFTER context has already been collected and the goal is known — the questions that sharpen a plan, not the ones that scope the request. This is the `implement`-intent interview job-orchestrator runs at 0.3. To pin down a vague request before any context is gathered, use `interviewer` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "/interview"
|
|
6
6
|
- "Interview"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interviewer
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when a request is ambiguous and must be pinned down BEFORE any context is collected — the entry-point interview that turns a vague or expensive ask into a scoped brief. This is the `custom`-intent gate job-orchestrator runs at 0.1.5. For clarifying implementation specifics AFTER context is already collected, use `interview` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "Interview me"
|
|
6
6
|
- "Ask me questions"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interviewer
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when a request is ambiguous and must be pinned down BEFORE any context is collected — the entry-point interview that turns a vague or expensive ask into a scoped brief. This is the `custom`-intent gate job-orchestrator runs at 0.1.5. For clarifying implementation specifics AFTER context is already collected, use `interview` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "Interview me"
|
|
6
6
|
- "Ask me questions"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interviewer
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when a request is ambiguous and must be pinned down BEFORE any context is collected — the entry-point interview that turns a vague or expensive ask into a scoped brief. This is the `custom`-intent gate job-orchestrator runs at 0.1.5. For clarifying implementation specifics AFTER context is already collected, use `interview` instead."
|
|
4
4
|
triggers:
|
|
5
5
|
- "Interview me"
|
|
6
6
|
- "Ask me questions"
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-entrypoint-distiller
|
|
3
3
|
description: Use when the user asks to split, decompose, distill, or refactor a large AGENTS.md or CLAUDE.md into Metaproject rules and project-specific skills while keeping root entrypoints compact.
|
|
4
|
+
triggers:
|
|
5
|
+
- "distill AGENTS.md"
|
|
6
|
+
- "split CLAUDE.md"
|
|
7
|
+
- "разнеси CLAUDE.md по правилам"
|
|
4
8
|
metadata:
|
|
5
9
|
version: "1.0.0"
|
|
6
10
|
category: platform
|
|
@@ -5,8 +5,7 @@ description: |
|
|
|
5
5
|
Use when: reviewing code for architectural violations — layer violations, dependency direction
|
|
6
6
|
mistakes, module boundary coupling, SOLID principle breaches, NestJS module/provider structure,
|
|
7
7
|
React MVVM boundary violations, or MobX store layer misplacement.
|
|
8
|
-
|
|
9
|
-
or dispatched by review-orchestrator with --architecture or --backend.
|
|
8
|
+
Dispatched by review-orchestrator with --architecture or --backend.
|
|
10
9
|
NOT for: style/naming preferences, logic correctness bugs, or security vulnerabilities.
|
|
11
10
|
triggers:
|
|
12
11
|
- "review architecture"
|
|
@@ -3,8 +3,8 @@ name: review-backend
|
|
|
3
3
|
model_tier: standard
|
|
4
4
|
description: |
|
|
5
5
|
Use when: reviewing NestJS backend changes — API design, service layer, DTO validation,
|
|
6
|
-
database patterns, and TypeScript correctness.
|
|
7
|
-
|
|
6
|
+
database patterns, and TypeScript correctness. Dispatched by review-orchestrator
|
|
7
|
+
with the --backend flag.
|
|
8
8
|
NOT for: frontend patterns, MobX, React components, general security vulnerabilities
|
|
9
9
|
(use review-security-code for XSS/injection/auth-bypass), or performance profiling
|
|
10
10
|
(use review-performance).
|
|
@@ -6,8 +6,7 @@ description: |
|
|
|
6
6
|
function/class level — meaningful names, small functions, single level of abstraction,
|
|
7
7
|
argument count, error handling, DRY, comment quality, and SOLID (SRP, OCP, LSP, ISP, DIP)
|
|
8
8
|
as applied to individual classes and functions.
|
|
9
|
-
|
|
10
|
-
"review --clean-code", or dispatched by review-orchestrator.
|
|
9
|
+
Dispatched by review-orchestrator.
|
|
11
10
|
NOT for: architectural layer violations (review-architecture), naming convention formatting
|
|
12
11
|
(review-style), logic correctness bugs (review-logic), or security (review-security-code).
|
|
13
12
|
triggers:
|
|
@@ -6,6 +6,10 @@ description: |
|
|
|
6
6
|
direction, feature-boundary leakage, abstraction stability, composition,
|
|
7
7
|
and blast-radius risks. Dispatched by review-orchestrator for
|
|
8
8
|
--core-boundaries, --project-conventions, --all, or src/core/** changes.
|
|
9
|
+
triggers:
|
|
10
|
+
- "review core boundaries"
|
|
11
|
+
- "review --core-boundaries"
|
|
12
|
+
- dispatched by review-orchestrator
|
|
9
13
|
metadata:
|
|
10
14
|
author: "MrCipherSmith"
|
|
11
15
|
version: "1.0.0"
|
|
@@ -7,6 +7,10 @@ description: |
|
|
|
7
7
|
boundaries, selection lifecycle, and large-graph performance. Dispatched by
|
|
8
8
|
review-orchestrator for --flow-graph, --project-conventions, --all, or
|
|
9
9
|
src/core/flow/** / graph abstraction changes.
|
|
10
|
+
triggers:
|
|
11
|
+
- "review flow graph"
|
|
12
|
+
- "review --flow-graph"
|
|
13
|
+
- dispatched by review-orchestrator
|
|
10
14
|
metadata:
|
|
11
15
|
author: "MrCipherSmith"
|
|
12
16
|
version: "1.0.0"
|
|
@@ -8,6 +8,10 @@ description: |
|
|
|
8
8
|
styling tokens, Storybook expectations, and local tooling rules. Dispatched
|
|
9
9
|
by review-orchestrator for --frontend-conventions, --project-conventions,
|
|
10
10
|
--all, or frontend src/**/*.ts(x) changes when local convention docs exist.
|
|
11
|
+
triggers:
|
|
12
|
+
- "review frontend conventions"
|
|
13
|
+
- "review --frontend-conventions"
|
|
14
|
+
- dispatched by review-orchestrator
|
|
11
15
|
metadata:
|
|
12
16
|
author: "MrCipherSmith"
|
|
13
17
|
version: "1.0.0"
|
|
@@ -6,8 +6,7 @@ description: |
|
|
|
6
6
|
race conditions, connection pool exhaustion, cache invalidation, missing indexes,
|
|
7
7
|
unbounded queues, missing backpressure, retry storms, idempotency gaps,
|
|
8
8
|
hot-path blocking I/O, and distributed systems anti-patterns.
|
|
9
|
-
|
|
10
|
-
"review concurrency", "review --highload", or dispatched by review-orchestrator.
|
|
9
|
+
Dispatched by review-orchestrator.
|
|
11
10
|
NOT for: frontend re-render performance (review-performance), general N+1 queries
|
|
12
11
|
(review-performance), clean code style (review-clean-code), or NestJS module structure
|
|
13
12
|
(review-architecture).
|
|
@@ -52,7 +52,7 @@ unified report sorted by severity. It does not perform any review logic itself.
|
|
|
52
52
|
```
|
|
53
53
|
Review Orchestrator Progress:
|
|
54
54
|
- [ ] Step 0: On a PR target, collect external comments — `keryx review comments collect`
|
|
55
|
-
- [ ] Step 1: Build Review Context Pack
|
|
55
|
+
- [ ] Step 1: Build Review Context Pack — PR metadata AND the PR's own description, scope, rules, context_doc summary, accepted memory, and the cross-repo contracts the diff consumes
|
|
56
56
|
- [ ] Step 2: Detect review mode (diff mode vs. path mode)
|
|
57
57
|
- [ ] Step 3: Build the bounded scope with `keryx review scope` — never by hand
|
|
58
58
|
- [ ] Step 3b: On a deep round, compute scope B with `keryx review blast-radius` — never by browsing — and KEEP the `--json` file; `review ingest --blast-radius <file>` is refused without it
|
|
@@ -204,9 +204,8 @@ keryx review complete <review-id-or-path>
|
|
|
204
204
|
[--finding <id> --disposition <state> --evidence <ref>]...
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
**An unrecognised option is refused, not ignored
|
|
208
|
-
|
|
209
|
-
`status: closed` and wrote nothing at all.
|
|
207
|
+
**An unrecognised option is refused, not ignored** — a misspelled flag exits
|
|
208
|
+
non-zero rather than printing `status: closed` and writing nothing at all.
|
|
210
209
|
|
|
211
210
|
`--verifications` takes what `review-verifier` returned. `--scope` takes the
|
|
212
211
|
whole `--json` output of `keryx review scope`, so the package records what the
|
|
@@ -462,8 +461,8 @@ Required content:
|
|
|
462
461
|
- Git/PR metadata: repo, branch, base, head, merge-base, PR number/URL when available.
|
|
463
462
|
- Scope summary: changed files grouped by domain, high-risk files, generated/ignored files.
|
|
464
463
|
- Requirements: issue URL, linked task docs, acceptance criteria extracted from `context_doc` when available.
|
|
465
|
-
- **The PR's own description**, fetched not assumed: `gh pr view <n> --json title,body`. See below.
|
|
466
|
-
- **Cross-repo contracts the diff depends on**, each pinned to the
|
|
464
|
+
- **The PR's own description**, fetched not assumed: `gh pr view <n> --json title,body`, into the typed `pr.body`. See below.
|
|
465
|
+
- **Cross-repo contracts the diff depends on**, in the typed `cross_repo`: each pinned to the ref you read it at, and each recording whether the producer has merged. See below.
|
|
467
466
|
- Rules: matched repository rules and convention docs by path.
|
|
468
467
|
- **Memory: accepted project memory intersecting the changed paths.** See below — this step is required, not best-effort.
|
|
469
468
|
- Decisions: why each reviewer was selected or skipped.
|
|
@@ -487,8 +486,17 @@ and not a pleasantry because unfiled housekeeping is raised again every round an
|
|
|
487
486
|
fixed in none — three consecutive rounds of "still worth rewriting" is the
|
|
488
487
|
recorded outcome of leaving it out of the findings array.
|
|
489
488
|
|
|
489
|
+
**The Stage 1 gate files it.** Handing the body to every reviewer is what makes
|
|
490
|
+
the body available; it is not what makes the comparison happen. A rule addressed
|
|
491
|
+
to everyone is owned by no one, and that is the state this finding sat in for
|
|
492
|
+
three rounds. The gate already holds the stated intent and the diff side by side,
|
|
493
|
+
so the comparison belongs there — see `## Stage 1 Gate — Spec Compliance`.
|
|
494
|
+
|
|
490
495
|
Same class, same severity: an approach that depends on another repository's change
|
|
491
|
-
being deployed first, with no deploy note saying so.
|
|
496
|
+
being deployed first, with no deploy note saying so. Note the boundary — that
|
|
497
|
+
`minor` is about the *description*. When the dependency is real and this change
|
|
498
|
+
can merge first, the blocker is filed against the call site instead; see
|
|
499
|
+
`### A producer that has not merged yet`.
|
|
492
500
|
|
|
493
501
|
### Cross-repo contracts are read, not assumed
|
|
494
502
|
|
|
@@ -499,15 +507,21 @@ the SHA:
|
|
|
499
507
|
```yaml
|
|
500
508
|
cross_repo:
|
|
501
509
|
- repo: vantage-backend
|
|
510
|
+
state: merged
|
|
502
511
|
sha: f5219d5d4
|
|
512
|
+
merge_order: independent
|
|
503
513
|
reason: "DQ report payload: which halves are null vs 0"
|
|
514
|
+
facts_pinned_round: 1
|
|
504
515
|
facts:
|
|
505
516
|
- "sqlScore/schemaDriftScore stay null when the half is absent"
|
|
506
517
|
- "sqlWeightPercentage/schemaDriftWeightPercentage init to 0.0 and are set unconditionally"
|
|
507
518
|
```
|
|
508
519
|
|
|
509
|
-
Put the facts in `review_context` so every reviewer shares one reading,
|
|
510
|
-
later round can tell a contract that moved from a reviewer that misread
|
|
520
|
+
Put the facts in `review_context.cross_repo` so every reviewer shares one reading,
|
|
521
|
+
and so a later round can tell a contract that moved from a reviewer that misread
|
|
522
|
+
it. The shape is typed in `review-context.schema.json`: `repo`, `reason`, `facts`
|
|
523
|
+
and `state` are required, `state: merged` requires the `sha`, and `state: open`
|
|
524
|
+
requires the `pr`.
|
|
511
525
|
|
|
512
526
|
The rule that follows for reviewers, and that belongs in the dispatch prompt:
|
|
513
527
|
|
|
@@ -517,9 +531,49 @@ The rule that follows for reviewers, and that belongs in the dispatch prompt:
|
|
|
517
531
|
> producer disproves, and a defect missed because the producer's actual default was
|
|
518
532
|
> assumed rather than read.
|
|
519
533
|
|
|
520
|
-
If the other repository is not available to you,
|
|
521
|
-
the dependent findings at `info`.
|
|
522
|
-
one is not.
|
|
534
|
+
If the other repository is not available to you, record it as
|
|
535
|
+
`state: unavailable` in `cross_repo` and leave the dependent findings at `info`.
|
|
536
|
+
An unavailable producer is a result. Assuming one is not.
|
|
537
|
+
|
|
538
|
+
A finding whose evidence lives in the producer sets `repo` on the finding itself.
|
|
539
|
+
`file` and `line` alone name a path in the repository under review, so without
|
|
540
|
+
`repo` a cross-repo claim cannot say where its evidence is — and the `info` rule
|
|
541
|
+
above then rests on nothing a later round can check.
|
|
542
|
+
|
|
543
|
+
### A producer that has not merged yet
|
|
544
|
+
|
|
545
|
+
`state: merged` is the easy case: the contract is on the producer's base branch,
|
|
546
|
+
you pin the SHA, and it stays where you pinned it. A **parallel pull request** —
|
|
547
|
+
the backend change your change was written against, still open — is a different
|
|
548
|
+
object, and pinning it the same way is wrong in three separate ways.
|
|
549
|
+
|
|
550
|
+
**Pin the pull request, not just the commit.** An open branch gets rebased and
|
|
551
|
+
squashed. A SHA read from it today names a commit that will not exist after the
|
|
552
|
+
merge, so `state: open` requires `pr` and the SHA becomes a note about when you
|
|
553
|
+
read it rather than an address a later reader can follow.
|
|
554
|
+
|
|
555
|
+
**Merge order is a `blocker`, not a note.** A missing deploy note in the PR body
|
|
556
|
+
is `minor` — that is a documentation finding and it stays where it is. The
|
|
557
|
+
operational case is not that one: when an entry is `state: open` with
|
|
558
|
+
`merge_order: producer_first`, and this change can merge without the producer,
|
|
559
|
+
**production breaks the moment it does**. That is a `blocker` under the existing
|
|
560
|
+
enumeration, not a new shape — the consumer calls what is not there, or reads a
|
|
561
|
+
default the producer has not changed yet, which is shape 1 or shape 2 in
|
|
562
|
+
`### \`blocker\` — merge-blocking, and nothing else`. File it against the consuming
|
|
563
|
+
call site rather than the description, and write the fix as what it is: a merge
|
|
564
|
+
gate, a flag, or a fallback, never an edit to a diff that may be perfectly
|
|
565
|
+
correct. Scope it exactly — both facts have to be recorded, an open producer AND
|
|
566
|
+
a producer-first order, and no gate already holding the merge. A
|
|
567
|
+
`merge_order: unknown` is a question to resolve, not a blocker to file.
|
|
568
|
+
|
|
569
|
+
**Re-read an open producer every round.** `facts` pinned in round 1 are a
|
|
570
|
+
statement about a branch that is still being written; by round 3 the contract may
|
|
571
|
+
have changed under a finding that still cites it. On each round, re-read every
|
|
572
|
+
entry with `state: open` and set `revalidated_round`. An entry whose
|
|
573
|
+
`revalidated_round` is behind the current round has not been checked this round,
|
|
574
|
+
and findings resting on it drop to `info` until it is. This is the same discipline
|
|
575
|
+
`prior_findings` already imposes on the local diff, applied to the one input that
|
|
576
|
+
is most likely to have moved.
|
|
523
577
|
|
|
524
578
|
### Memory (required)
|
|
525
579
|
|
|
@@ -624,16 +678,12 @@ A **fix round** is any review of work produced to answer earlier findings. Set
|
|
|
624
678
|
`is_fix_round: true` on every reviewer input, and populate `prior_findings` with
|
|
625
679
|
the earlier findings and the disposition the fix claimed for each.
|
|
626
680
|
|
|
627
|
-
**Nothing refuses a dispatch that omits them
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
cannot be pointed at it either. The sentence that stood here until flow 209 told
|
|
634
|
-
you the schema would reject a dispatch without `prior_findings`; it asserted an
|
|
635
|
-
enforcement that has never existed, which is the same class of claim this whole
|
|
636
|
-
package was written to delete.
|
|
681
|
+
**Nothing refuses a dispatch that omits them.** `reviewer-input.schema.json`
|
|
682
|
+
states the rule and no production TypeScript loads that schema; reviewer
|
|
683
|
+
dispatch is an action the host agent takes, not a `keryx` invocation, so there
|
|
684
|
+
is no point at which a malformed dispatch could be rejected. `reviewer-input` is
|
|
685
|
+
also absent from the `CONTRACTS` registry (`src/gdskills/contracts.ts`), so
|
|
686
|
+
`keryx skills contracts validate` cannot be pointed at it either.
|
|
637
687
|
|
|
638
688
|
So this is a requirement on you, unenforced, and the only evidence it was met is
|
|
639
689
|
the `prior_findings` array the reviewer actually receives. A reviewer that cannot
|
|
@@ -1117,7 +1167,8 @@ local frontend conventions reviewer.
|
|
|
1117
1167
|
|
|
1118
1168
|
## Stage 1 Gate — Spec Compliance
|
|
1119
1169
|
|
|
1120
|
-
**Run this FIRST, before dispatching quality reviewers,
|
|
1170
|
+
**Run this FIRST, before dispatching quality reviewers, whenever the change has a
|
|
1171
|
+
stated intent — an `issue_url`, a task doc, or a PR body.**
|
|
1121
1172
|
|
|
1122
1173
|
1. Fetch issue or task requirements.
|
|
1123
1174
|
2. Map changed files and functions to acceptance criteria.
|
|
@@ -1125,6 +1176,27 @@ local frontend conventions reviewer.
|
|
|
1125
1176
|
4. If there are unimplemented criteria: emit them as `blocker` findings in the final report and note them in `## Blockers`.
|
|
1126
1177
|
5. Continue dispatching the remaining reviewers regardless (spec gaps + quality issues both belong in the report).
|
|
1127
1178
|
|
|
1179
|
+
### With no issue and no task doc, the PR body is the spec
|
|
1180
|
+
|
|
1181
|
+
A pull request with nothing linked is the common case, not the exception, and the
|
|
1182
|
+
gate used to skip entirely on it — which meant the only written statement of what
|
|
1183
|
+
the change was for went unchecked precisely when it was the only one there. When
|
|
1184
|
+
`issue_url` and `context_doc` are both absent, read `pr.body` as the spec and run
|
|
1185
|
+
steps 2-4 against it. Nothing at all to read — no issue, no task doc, an empty
|
|
1186
|
+
body — is itself the finding: `minor`, that the change states no intent.
|
|
1187
|
+
|
|
1188
|
+
### This gate owns the description-vs-diff comparison
|
|
1189
|
+
|
|
1190
|
+
The `minor` for a description that promises an approach the diff does not take
|
|
1191
|
+
(see the Context Pack) is **filed here**. It was previously stated as a rule for
|
|
1192
|
+
"every reviewer" and owned by none, which is how it stayed a remark instead of a
|
|
1193
|
+
finding across three rounds. A domain reviewer reviews its domain; the one step
|
|
1194
|
+
that already holds intent and diff side by side is this one.
|
|
1195
|
+
|
|
1196
|
+
Run it on every round, not only the first. The drift the finding catches is
|
|
1197
|
+
created BY the rounds: the code moves to answer findings, the body does not, and
|
|
1198
|
+
whoever reads the merge commit a year later reads the body.
|
|
1199
|
+
|
|
1128
1200
|
---
|
|
1129
1201
|
|
|
1130
1202
|
## Dispatching Reviewers
|
|
@@ -1328,6 +1400,18 @@ Everything else is at most `major`. "This will definitely cause problems later"
|
|
|
1328
1400
|
is not one of the four. Neither is "this violates the architecture", "this fails
|
|
1329
1401
|
the linter", or "this is how the last outage started".
|
|
1330
1402
|
|
|
1403
|
+
**An unshipped dependency is shape 1 or shape 2, and the list stays closed.**
|
|
1404
|
+
When a producer is recorded `state: open` with `merge_order: producer_first` and
|
|
1405
|
+
nothing stops this change merging first, ask the enumeration's own question —
|
|
1406
|
+
what happens at runtime. The consumer calls what is not there (shape 1) or reads
|
|
1407
|
+
the default the producer has not changed yet (shape 2). That is why it is a
|
|
1408
|
+
`blocker` without a fifth shape being invented for it. Two things follow from
|
|
1409
|
+
its being an ordering fault rather than a coding one: file it against the
|
|
1410
|
+
consuming call site, and say in the fix that the remedy is a merge gate, a flag,
|
|
1411
|
+
or a fallback — never a change to the diff, which may be entirely correct. A
|
|
1412
|
+
missing deploy note with no recorded producer state behind it is not this; that
|
|
1413
|
+
is the `minor` in the Context Pack. See `### A producer that has not merged yet`.
|
|
1414
|
+
|
|
1331
1415
|
### `major` / `minor` / `info` — the boundary test
|
|
1332
1416
|
|
|
1333
1417
|
Ask one question, and ask it of the **finding**, not of the code:
|
|
@@ -1459,6 +1543,7 @@ All findings from all sub-reviewers must be normalized to this format before con
|
|
|
1459
1543
|
|
|
1460
1544
|
- **Severity**: blocker | major | minor | info
|
|
1461
1545
|
- **File**: path/to/file.ts:line
|
|
1546
|
+
- **Repo**: producer repository — only when the evidence is not in the repository under review
|
|
1462
1547
|
- **Problem**: what is wrong
|
|
1463
1548
|
- **Why it matters**: impact on correctness / safety / maintainability / UX
|
|
1464
1549
|
- **Fix**: concrete suggestion
|
|
@@ -23,6 +23,58 @@
|
|
|
23
23
|
"object",
|
|
24
24
|
"null"
|
|
25
25
|
],
|
|
26
|
+
"description": "The pull request under review, when there is one. `body` is the author's own statement of what the change does, and it is checkable against the diff — it is typed here rather than left to convention because the Context Pack prose told reviewers to read `pr.body` while the schema declared no such field, so nothing carried it and nothing could tell a body that was never fetched from one that was empty.",
|
|
27
|
+
"properties": {
|
|
28
|
+
"number": {
|
|
29
|
+
"type": [
|
|
30
|
+
"integer",
|
|
31
|
+
"null"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"url": {
|
|
35
|
+
"type": [
|
|
36
|
+
"string",
|
|
37
|
+
"null"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"title": {
|
|
41
|
+
"type": [
|
|
42
|
+
"string",
|
|
43
|
+
"null"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"body": {
|
|
47
|
+
"type": [
|
|
48
|
+
"string",
|
|
49
|
+
"null"
|
|
50
|
+
],
|
|
51
|
+
"description": "Fetched, not assumed: `gh pr view <n> --json title,body`. Null means the fetch did not happen or returned nothing; an empty string means the author wrote no description, which is a different fact and a reportable one."
|
|
52
|
+
},
|
|
53
|
+
"state": {
|
|
54
|
+
"type": [
|
|
55
|
+
"string",
|
|
56
|
+
"null"
|
|
57
|
+
],
|
|
58
|
+
"enum": [
|
|
59
|
+
"open",
|
|
60
|
+
"merged",
|
|
61
|
+
"closed",
|
|
62
|
+
null
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"base": {
|
|
66
|
+
"type": [
|
|
67
|
+
"string",
|
|
68
|
+
"null"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"head": {
|
|
72
|
+
"type": [
|
|
73
|
+
"string",
|
|
74
|
+
"null"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
26
78
|
"additionalProperties": true
|
|
27
79
|
},
|
|
28
80
|
"scope": {
|
|
@@ -71,6 +123,129 @@
|
|
|
71
123
|
"type": "string"
|
|
72
124
|
}
|
|
73
125
|
},
|
|
126
|
+
"cross_repo": {
|
|
127
|
+
"type": "array",
|
|
128
|
+
"description": "Contracts owned by another service that this diff consumes — a payload shape, a status enum, a timeout, a permission, a default. Each entry is one reading of the producer, shared by every reviewer, so that a later round can tell a contract that moved from a reviewer that misread it. An entry is a RECORD OF READING: an unavailable producer is a result and belongs here as `state: unavailable`, whereas an assumed one belongs nowhere.",
|
|
129
|
+
"items": {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"required": [
|
|
132
|
+
"repo",
|
|
133
|
+
"reason",
|
|
134
|
+
"facts",
|
|
135
|
+
"state"
|
|
136
|
+
],
|
|
137
|
+
"properties": {
|
|
138
|
+
"repo": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"minLength": 1
|
|
141
|
+
},
|
|
142
|
+
"reason": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"minLength": 1,
|
|
145
|
+
"description": "What this diff needs from the producer, in one line."
|
|
146
|
+
},
|
|
147
|
+
"facts": {
|
|
148
|
+
"type": "array",
|
|
149
|
+
"minItems": 1,
|
|
150
|
+
"items": {
|
|
151
|
+
"type": "string"
|
|
152
|
+
},
|
|
153
|
+
"description": "What the producer actually says, read at the pinned ref. A claim about another service's behaviour with no `file:line` behind it at a pinned ref is `info`, not `major`, however confident — both failure modes are recorded: a finding the producer disproves, and a defect missed because the producer's real default was assumed rather than read."
|
|
154
|
+
},
|
|
155
|
+
"state": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"enum": [
|
|
158
|
+
"merged",
|
|
159
|
+
"open",
|
|
160
|
+
"unavailable"
|
|
161
|
+
],
|
|
162
|
+
"description": "Where the contract lives right now. `merged` is on the producer's own base branch and is pinned by `sha`. `open` is a parallel pull request that has not landed: its branch will be rebased or squashed, so a sha pinned today names a commit that will not exist after the merge, and the contract itself can still change. `unavailable` means the producer could not be read."
|
|
163
|
+
},
|
|
164
|
+
"sha": {
|
|
165
|
+
"type": [
|
|
166
|
+
"string",
|
|
167
|
+
"null"
|
|
168
|
+
],
|
|
169
|
+
"description": "The commit the facts were read at. Required when `state` is `merged`."
|
|
170
|
+
},
|
|
171
|
+
"pr": {
|
|
172
|
+
"type": [
|
|
173
|
+
"string",
|
|
174
|
+
"null"
|
|
175
|
+
],
|
|
176
|
+
"description": "The producer's pull request, when the contract is not merged yet."
|
|
177
|
+
},
|
|
178
|
+
"branch": {
|
|
179
|
+
"type": [
|
|
180
|
+
"string",
|
|
181
|
+
"null"
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
"merge_order": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"enum": [
|
|
187
|
+
"producer_first",
|
|
188
|
+
"consumer_first",
|
|
189
|
+
"independent",
|
|
190
|
+
"unknown"
|
|
191
|
+
],
|
|
192
|
+
"default": "unknown",
|
|
193
|
+
"description": "Which side has to ship first for production to stay correct. `producer_first` on a `state: open` entry is the case where merging THIS change first breaks production, and it is a blocker rather than the `minor` filed for a missing deploy note."
|
|
194
|
+
},
|
|
195
|
+
"facts_pinned_round": {
|
|
196
|
+
"type": [
|
|
197
|
+
"integer",
|
|
198
|
+
"null"
|
|
199
|
+
],
|
|
200
|
+
"description": "The review round the facts were read in."
|
|
201
|
+
},
|
|
202
|
+
"revalidated_round": {
|
|
203
|
+
"type": [
|
|
204
|
+
"integer",
|
|
205
|
+
"null"
|
|
206
|
+
],
|
|
207
|
+
"description": "The last round the producer was re-read. An entry with `state: open` that was pinned in round 1 and never revalidated is stale by round 3: a parallel pull request is precisely the thing that moves between rounds."
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"allOf": [
|
|
211
|
+
{
|
|
212
|
+
"if": {
|
|
213
|
+
"properties": {
|
|
214
|
+
"state": {
|
|
215
|
+
"const": "merged"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"required": [
|
|
219
|
+
"state"
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
"then": {
|
|
223
|
+
"required": [
|
|
224
|
+
"sha"
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"if": {
|
|
230
|
+
"properties": {
|
|
231
|
+
"state": {
|
|
232
|
+
"const": "open"
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
"required": [
|
|
236
|
+
"state"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
"then": {
|
|
240
|
+
"required": [
|
|
241
|
+
"pr"
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
],
|
|
246
|
+
"additionalProperties": true
|
|
247
|
+
}
|
|
248
|
+
},
|
|
74
249
|
"memory": {
|
|
75
250
|
"type": "object",
|
|
76
251
|
"required": [
|
|
@@ -60,6 +60,13 @@
|
|
|
60
60
|
"info"
|
|
61
61
|
]
|
|
62
62
|
},
|
|
63
|
+
"repo": {
|
|
64
|
+
"type": [
|
|
65
|
+
"string",
|
|
66
|
+
"null"
|
|
67
|
+
],
|
|
68
|
+
"description": "Which repository `file` and `line` are in. Null, the default, means the repository under review. A cross-repo claim names the producer here and pins the ref it was read at in `evidence`; without this field a finding about another service's behaviour could not say where its evidence lived, so the rule that such a claim is `info` unless it has a `file:line` at a pinned ref could not be checked by anything but the reviewer's word. Kept identical to src/gdskills/contracts/review-finding.schema.json, which is stricter (additionalProperties: false) and would reject a finding carrying `repo` if the property were declared only here."
|
|
69
|
+
},
|
|
63
70
|
"file": {
|
|
64
71
|
"type": [
|
|
65
72
|
"string",
|
|
@@ -4,9 +4,8 @@ model_tier: standard
|
|
|
4
4
|
description: |
|
|
5
5
|
Use when: a developer has received PR review comments and wants to understand them,
|
|
6
6
|
check whether they are still true of the code, act on them, or extract patterns
|
|
7
|
-
from them.
|
|
8
|
-
|
|
9
|
-
comment, planning the fix, driving it to a merged state and answering each reviewer.
|
|
7
|
+
from them. With `--fix`, also validates every comment, plans the fix, drives it to
|
|
8
|
+
a merged state and answers each reviewer.
|
|
10
9
|
NOT for: reviewing code directly — this skill reads human or bot PR feedback and
|
|
11
10
|
makes it actionable. To review code, use the domain review skills.
|
|
12
11
|
triggers:
|