code-jig 0.12.0__py3-none-any.whl

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 (52) hide show
  1. code_jig-0.12.0.dist-info/METADATA +154 -0
  2. code_jig-0.12.0.dist-info/RECORD +52 -0
  3. code_jig-0.12.0.dist-info/WHEEL +4 -0
  4. code_jig-0.12.0.dist-info/entry_points.txt +2 -0
  5. code_jig-0.12.0.dist-info/licenses/LICENSE +202 -0
  6. codejig/__init__.py +1 -0
  7. codejig/__main__.py +106 -0
  8. codejig/_core/VERSION +2 -0
  9. codejig/_core/bench/requirements.toml +4 -0
  10. codejig/_core/core/AGENTS.core.md +9 -0
  11. codejig/_core/core/agents/explorer.toml +24 -0
  12. codejig/_core/core/agents/judge.toml +19 -0
  13. codejig/_core/core/agents/reviewer.toml +10 -0
  14. codejig/_core/core/tiers.toml +4 -0
  15. codejig/_core/skills/bug-hunt/SKILL.md +131 -0
  16. codejig/_core/skills/code-analysis/SKILL.md +72 -0
  17. codejig/_core/skills/codegen/SKILL.md +46 -0
  18. codejig/_core/skills/cross-review/SKILL.md +32 -0
  19. codejig/_core/skills/grilling/SKILL.md +60 -0
  20. codejig/_core/skills/hld-trace/SKILL.md +69 -0
  21. codejig/_core/skills/improve/SKILL.md +38 -0
  22. codejig/_core/skills/redacao/SKILL.md +114 -0
  23. codejig/_core/skills/redacao/checar.py +75 -0
  24. codejig/_core/skills/redacao/reference.md +118 -0
  25. codejig/_core/skills/regression-tests/SKILL.md +53 -0
  26. codejig/_core/skills/remove-ai-attribution/SKILL.md +33 -0
  27. codejig/_core/skills/skill-validate/SKILL.md +58 -0
  28. codejig/_core/skills/web-consensus/SKILL.md +55 -0
  29. codejig/analyze.py +499 -0
  30. codejig/atomicwrite.py +49 -0
  31. codejig/collect.py +311 -0
  32. codejig/doctor.py +370 -0
  33. codejig/evidence.py +418 -0
  34. codejig/feedback.py +165 -0
  35. codejig/gitgate.py +278 -0
  36. codejig/hooks.py +64 -0
  37. codejig/humanize.py +206 -0
  38. codejig/install.py +381 -0
  39. codejig/managed.py +64 -0
  40. codejig/migrate.py +515 -0
  41. codejig/overlay.py +43 -0
  42. codejig/paths.py +40 -0
  43. codejig/probe.py +136 -0
  44. codejig/review.py +73 -0
  45. codejig/scrub.py +255 -0
  46. codejig/skillcheck.py +400 -0
  47. codejig/skilllint.py +99 -0
  48. codejig/sources.py +248 -0
  49. codejig/tiers.py +63 -0
  50. codejig/tokens.py +118 -0
  51. codejig/trace.py +137 -0
  52. codejig/watermark.py +147 -0
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: bug-hunt
3
+ description: Use when the user asks to hunt for bugs nobody reported, audit a codebase or a path for latent bugs and vulnerabilities, fuzz code, write property-based tests, run mutation testing, or check whether the tests would catch a regression.
4
+ ---
5
+
6
+ # Bug hunt
7
+
8
+ Find real bugs nobody reported, and prove each one with a failing test. Deterministic tools pick the candidates; you judge them in context; generated inputs and mutations find what reading misses.
9
+
10
+ ## Scope
11
+
12
+ Take scope from the request: a path, a category (security, logic, data integrity, error handling, performance), a minimum severity. Default: the whole repo, or `--base main` on a feature branch.
13
+
14
+ ## 1. Recon, all deterministic
15
+
16
+ With the code-jig core on `PYTHONPATH`, or the `code-jig` launcher on `PATH`:
17
+
18
+ ```
19
+ code-jig analyze --json [--base main] [path]
20
+ git ls-files | grep -E "(^|/)\.env($|\.)|\.(pem|key|pfx|p12)$|credentials\.json$|secrets?\.(json|ya?ml)$"
21
+ git log --oneline -i -E --grep="security|cve|vuln|bypass|injection|xss|csrf|auth" -n 30
22
+ git log --since=90.days --name-only --format= | sort | uniq -c | sort -rn | head -20
23
+ git grep -n -i -E "(TODO|FIXME|HACK|XXX).*(security|auth|unsafe|bypass|vuln|temp)|disable.*(auth|ssl|tls|verif)|skip.*validat"
24
+ ```
25
+
26
+ PowerShell: write a `NAME=value command` line as `$env:NAME = 'value'; command`, replace `grep -E` with `Select-String -Pattern`, and the churn line with `git log --since=90.days --name-only --format= | Group-Object | Sort-Object Count -Descending | Select-Object -First 20 Count, Name`.
27
+
28
+ - A tracked `.env`, key or credentials file is CRITICAL before anything else: open it, confirm it holds a real-looking secret and not a placeholder or example value, and report it first. Removing it does not un-leak it; the secret must be rotated.
29
+ - Past fix commits show what this codebase gets wrong; read them and look for the same mistake elsewhere.
30
+ - Hotspots, files that are both in the churn list and in `analyze`'s complexity findings, get read first.
31
+ - Security TODOs are bugs the authors already found.
32
+ - `analyze` already reports vulnerable dependencies (osv-scanner, and NuGet audit warnings from `dotnet build`) and dead code (vulture, knip); a function nobody calls is a bug hiding place and a deletion candidate.
33
+
34
+ ### Dependencies, deeper
35
+
36
+ - One package against osv.dev, sending only its name and version: `curl -s -d '{"package":{"name":"lodash","ecosystem":"npm"},"version":"4.17.20"}' https://api.osv.dev/v1/query` (PowerShell: `Invoke-RestMethod -Method Post -Uri https://api.osv.dev/v1/query -ContentType application/json -Body '{"package":{"name":"lodash","ecosystem":"npm"},"version":"4.17.20"}'`). The fixed versions are in `vulns[].affected[].ranges[].events[].fixed`.
37
+ - Upgrade suggestions for npm and Maven, only when the user asked for fixes: `osv-scanner fix --strategy=in-place -L package-lock.json`. It rewrites the lockfile, so review the diff and run the tests. Its default `--data-source deps.dev` sends package names to deps.dev, and `--data-source native` sends them to the package registry; add `--offline-vulnerabilities --download-offline-databases` so the vulnerability matching itself stays local.
38
+ - .NET: `DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet list package --vulnerable --include-transitive --format json`. Restore already asks nuget.org for advisories.
39
+
40
+ ### Infrastructure code
41
+
42
+ - Docker, Kubernetes, Terraform, ARM: `trivy config --disable-telemetry --skip-version-check --skip-check-update --format json .` (the bundled checks; no telemetry, no version or check download).
43
+ - Bicep and ARM against Azure's Well-Architected rules: `Install-Module -Name PSRule.Rules.Azure -Scope CurrentUser`. Turn on expansion before scanning, or the templates are not read: in `ps-rule.yaml` set `configuration: { AZURE_BICEP_FILE_EXPANSION: true, AZURE_PARAMETER_FILE_EXPANSION: true }`, or for one run `$Env:PSRULE_CONFIGURATION_AZURE_BICEP_FILE_EXPANSION = 'true'` and `$Env:PSRULE_CONFIGURATION_AZURE_PARAMETER_FILE_EXPANSION = 'true'`. Then `Invoke-PSRule -Format File -InputPath ./infra -Module PSRule.Rules.Azure -Outcome Fail`.
44
+
45
+ ## 2. Confirm: the reality gate
46
+
47
+ For every candidate, read at least 20 lines around it and answer: is this a real problem in this code's actual context? A pattern match on safe code is a false positive; drop it silently. Skip test and mock code, with one exception: a test that asserts the buggy behaviour is reported together with the bug it locks in.
48
+
49
+ | Severity | Meaning |
50
+ |---|---|
51
+ | CRITICAL | Exploitable now: auth bypass, injection, remote code execution, data loss |
52
+ | HIGH | Likely to break in normal use, or a real security weakness |
53
+ | MEDIUM | Needs specific conditions, or a missing guard on a reachable path |
54
+ | LOW | Fragile code with no current impact |
55
+
56
+ Calibrate down: needs authentication plus unusual conditions is MEDIUM, not CRITICAL. A purely theoretical concern is not reported.
57
+
58
+ When a bug is confirmed, check its siblings; bugs cluster.
59
+
60
+ | Found | Also check |
61
+ |---|---|
62
+ | Missing authorization on an endpoint or controller action | The other actions in the same controller or router |
63
+ | String-built SQL or command | Every other query or process call in the module |
64
+ | Unbounded query or loop over request data | The other list endpoints of the same API |
65
+ | Missing input validation | The other POST, PUT and PATCH handlers of the route |
66
+ | Swallowed exception | The other catch blocks in the same layer |
67
+ | Hardcoded credential | The other config files in the same folder |
68
+ | Disposable or subscription not released | The other resources in the same class or component |
69
+
70
+ With many candidates and a subagent tool available, split them by category, one subagent each on the default role (judging a bug is not a lookup, so not `explorer`), and give every subagent this reality gate and severity table.
71
+
72
+ ## 3. Prove
73
+
74
+ - A confirmed bug gets a failing test that reproduces it (the `regression-tests` skill) when the code has a test framework; otherwise record the command and output that reproduce it. Fix it only if the user asked for fixes.
75
+ - Logic that looks wrong but resists a single example gets a property test or a fuzz run.
76
+ - For hotspot files, run mutation testing to see what the existing tests would miss.
77
+
78
+ ### Property-based tests
79
+
80
+ State a rule that holds for all inputs; keep the shrunk counterexample as a fixed test.
81
+
82
+ | Stack | Library | Shape |
83
+ |---|---|---|
84
+ | Python | Hypothesis | `@given(st.text())` on a pytest test |
85
+ | TS/JS | fast-check | `fc.assert(fc.property(fc.string(), (s) => ...))` |
86
+ | .NET | FsCheck (`[Property]` with FsCheck.Xunit) or CsCheck (`Gen.Int.Sample(i => ...)`) | |
87
+
88
+ Good properties: decode(encode(x)) == x; sorting is idempotent; a result stays inside its bounds; the fast path equals a slow reference.
89
+
90
+ ### Coverage-guided fuzzing
91
+
92
+ | Stack | Tool | Run |
93
+ |---|---|---|
94
+ | Python | atheris (Linux x86_64 wheels only; on Windows run it in WSL) | a script calling `atheris.Setup(sys.argv, test_one_input)` and `atheris.Fuzz()`, run with `-max_total_time=60` |
95
+ | TS/JS | jazzer.js | `npx jazzer <fuzz-target-module> -- -max_total_time=60`, the module exporting `fuzz(data)` |
96
+ | .NET | SharpFuzz | a console project with the `SharpFuzz` package and the target assembly instrumented by the `sharpfuzz` tool (`dotnet tool install SharpFuzz.CommandLine` in a tool manifest). With afl-fuzz (Linux) the harness calls `Fuzzer.OutOfProcess.Run(stream => ...)`; with libfuzzer-dotnet (Windows and Linux) it calls `Fuzzer.LibFuzzer.Run(span => ...)`. Follow its README (https://github.com/Metalnem/sharpfuzz) and `docs/libFuzzer.md` |
97
+ | HTTP APIs | schemathesis | `schemathesis run http://localhost:<port>/openapi.json`, only against a local instance |
98
+
99
+ Bound every run by time. Each crashing input becomes a test.
100
+
101
+ ### Mutation testing
102
+
103
+ The tool flips conditions and removes calls, then reruns the tests; a surviving mutant is a regression the tests would miss. Keep it to the hotspot or changed files.
104
+
105
+ | Stack | Tool | Run |
106
+ |---|---|---|
107
+ | Python | mutmut (POSIX; on Windows use WSL) | `[tool.mutmut]` with `source_paths = ["pkg/module.py"]` in `pyproject.toml`, then `mutmut run`, `mutmut results`, `mutmut show <mutant>`. mutmut 3 refuses code imported as `src.…`: run it on a scratch copy with the package renamed. List every non-Python file the tests read in `also_copy`. |
108
+ | TS/JS | Stryker | `npx stryker run --mutate "src/module.ts"` (`npx stryker init` once) |
109
+ | .NET | Stryker.NET | `dotnet new tool-manifest` once, `dotnet tool install dotnet-stryker`, then `DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet stryker --mutate "**/Module.cs"` or `--since:main` |
110
+
111
+ Each surviving mutant gets a test that kills it, or a sentence on why it is equivalent to the original.
112
+
113
+ ### Techniques without a new tool
114
+
115
+ - **Bisect a regression**: `git bisect start <bad> <good>`, then `git bisect run <command that runs the failing test>`; the first bad commit names the cause. Bisect writes inside `.git`, which the Codex sandbox keeps read-only, so request escalation for these commands, and finish with `git bisect reset`.
116
+ - **Flaky tests**: shuffle and repeat. pytest with the `pytest-randomly` plugin installed (it shuffles every run) and a loop; `npx jest --randomize`; for .NET, run `DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet test --filter <name>` in a loop of 20. A test that fails only sometimes hides a race, shared state or an order dependency.
117
+ - **Differential testing**: run the old and the new implementation (or two libraries) on the same generated inputs and compare.
118
+ - **Metamorphic relations**: when the right answer is unknown, test relations instead: sorting a shuffled list gives the same result, filtering twice equals filtering once, a search for a superset term returns a superset.
119
+ - **Invariants**: assert what must always hold at module boundaries in tests (totals add up, IDs stay unique) and let property tests drive them.
120
+
121
+ ## 4. Report
122
+
123
+ Most severe first, one block per finding:
124
+
125
+ ```
126
+ CRITICAL Tenant check missing on invoice download
127
+ src/Api/InvoicesController.cs:88
128
+ Any signed-in user can fetch another tenant's invoice by ID. Proven by InvoicesTests.Download_OtherTenant_Forbidden (fails today).
129
+ ```
130
+
131
+ End with counts per severity, what was scanned, which tools `analyze` skipped, and the fuzzing and mutation runs with their durations. No finding without a location and its proof from step 3: a failing test, or where there is no test framework, the command and output that reproduce it.
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: code-analysis
3
+ description: Use when the user asks to analyse code quality, find bugs, code smells, complexity, duplication, security issues, leaked secrets or vulnerable dependencies, or asks what Sonar or SonarQube would complain about.
4
+ ---
5
+
6
+ # Code analysis
7
+
8
+ `code-jig analyze` runs the local analyzers for every stack it finds (.NET, Node, Python) and prints one summary grouped the way Sonar groups issues. It never downloads a tool and never sends code anywhere.
9
+
10
+ ## Run it
11
+
12
+ From the repository root run `code-jig analyze` (the launcher installed with the pack). Without the launcher, point `PYTHONPATH` at the code-jig checkout, the folder that contains `codejig/` (POSIX: `PYTHONPATH=<checkout> python -m codejig analyze`; Windows PowerShell: `$env:PYTHONPATH = "<checkout>"; py -3 -m codejig analyze`):
13
+
14
+ ```
15
+ code-jig analyze # whole repo
16
+ code-jig analyze --base main # only files changed since main, plus untracked ones
17
+ code-jig analyze --top 30 # more findings per category
18
+ code-jig analyze --json # machine-readable
19
+ ```
20
+
21
+ Exit 0 means clean, 1 means findings or a tool error, 2 means no project, a bad `--base`, or no analyzer installed.
22
+
23
+ ## What runs
24
+
25
+ | Tool | Stack | Finds |
26
+ |---|---|---|
27
+ | lizard | all | Cognitive complexity (Sonar's metric, limit 15), cyclomatic complexity (15), functions over 100 lines or 7 parameters, duplicated blocks |
28
+ | ruff | Python | Bugs, smells, security (`S` rules, the bandit set) |
29
+ | vulture | Python | Dead code at 80% confidence and up: unused imports, variables and arguments, unreachable code, conditions that can never be true. Unused functions and classes score 60%: for a full sweep, set `[tool.vulture]` with `paths` and `min_confidence = 60` in `pyproject.toml`, which `analyze` then uses as-is |
30
+ | mypy | Python, with a mypy config | Type errors |
31
+ | eslint | Node, with an eslint config | Whatever the config enables; `sonarjs/*` and `security/*` rules are grouped as complexity or security |
32
+ | knip | Node | Unused files, exports, types and dependencies; dependencies used but not listed, and imports that do not resolve |
33
+ | tsc | Node, with `tsconfig.json` | Type errors |
34
+ | dotnet build | .NET | Compiler and analyzer warnings, SonarAnalyzer and Roslynator included when the project references them, and NuGet audit warnings (NU1901-NU1904) for vulnerable packages; restore asks nuget.org for advisories, sending package names |
35
+ | semgrep | all, with `.semgrep.yml` or `.semgrep/` | Your own local rules only, run with `--metrics=off` |
36
+ | gitleaks | all | Secrets in the working tree, uncommitted files included, and in the git history; the secret itself is never printed |
37
+ | osv-scanner | all | Known vulnerabilities in lockfiles, with `--offline`: the first run downloads the vulnerability database, no project data leaves |
38
+
39
+ `code-jig analyze` itself sets `DOTNET_CLI_TELEMETRY_OPTOUT=1`, `SEMGREP_SEND_METRICS=off` and `KIOTA_CLI_TELEMETRY_OPTOUT=1` for every tool, in any shell; there is nothing to export. Missing tools are listed as skipped with an install hint.
40
+
41
+ Analysis executes the repo's own code: `eslint.config.js`, MSBuild targets, mypy plugins and the tools in `node_modules/.bin`. Run it only where you would run the repo's tests.
42
+
43
+ ## Fix in this order
44
+
45
+ 1. `secret`: report it to the user first: the secret must be rotated (only its owner can, and only with their approval), then removed from the code. Removing it from the code does not un-leak it.
46
+ 2. `security`, then `dependency` (upgrade to the fixed version osv-scanner names).
47
+ 3. `bug` and `type`.
48
+ 4. `complexity`: extract functions, return early, replace flag arguments, split by responsibility. Behaviour must not change; run the tests before and after.
49
+ 5. `unused`: remove the dead code (git keeps it), after checking reflection, dependency injection, public API and framework entry points that tools cannot see.
50
+ 6. `duplication`: extract the shared code only when both copies change for the same reason.
51
+
52
+ Rerun with `--base` and the branch this one will merge into (`main` when it exists; check with `git rev-parse --verify main`) to confirm the branch is clean. With no such branch, rerun on the whole repository.
53
+
54
+ ## Add Sonar's rules to a repo
55
+
56
+ Only with the user's agreement, as dev dependencies:
57
+
58
+ - .NET: in `Directory.Build.props`, `<PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="all" />` and `<PackageReference Include="Roslynator.Analyzers" PrivateAssets="all" />`. Raise rules in `.editorconfig`, for example `dotnet_diagnostic.S3776.severity = warning`. SonarAnalyzer is under SonarSource's source-available licence, free to use but not open source; Roslynator and the built-in CA rules are the open-source alternative. Run dotnet commands with `DOTNET_CLI_TELEMETRY_OPTOUT=1`.
59
+ - Node: `npm install -D eslint eslint-plugin-sonarjs eslint-plugin-security typescript-eslint`, then in `eslint.config.mjs`:
60
+
61
+ ```js
62
+ import sonarjs from "eslint-plugin-sonarjs";
63
+ import security from "eslint-plugin-security";
64
+ export default [sonarjs.configs.recommended, security.configs.recommended];
65
+ ```
66
+
67
+ - Python: `pip install ruff mypy vulture` in the project's dev dependencies, plus a `[tool.mypy]` section. For stricter typing, pyright in strict mode (`"typeCheckingMode": "strict"` in `pyrightconfig.json`) catches more than mypy's defaults; run it as `pyright --outputjson`.
68
+ - TypeScript: `typescript-eslint`'s `strictTypeChecked` config adds `no-floating-promises` and `no-misused-promises`, which catch unawaited async calls; it needs `parserOptions.projectService: true`. Add `knip` as a dev dependency.
69
+ - C#: `<Nullable>enable</Nullable>` and `<WarningsAsErrors>nullable</WarningsAsErrors>` turn null-reference warnings into build errors.
70
+ - All stacks: `pip install lizard`; gitleaks and osv-scanner from their GitHub releases; semgrep only with local rule files.
71
+
72
+ What a Sonar server adds that this does not: taint analysis across files and the history dashboard.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: codegen
3
+ description: Use when the user asks to generate an API client or server stubs from an OpenAPI spec, scaffold a project or component, or apply the same mechanical change across many files (a codemod, a rename, an API migration).
4
+ ---
5
+
6
+ # Code generation
7
+
8
+ Generators and codemods are deterministic: the same input gives the same output, at no token cost. Prefer them to writing repetitive code by hand.
9
+
10
+ ## Rules
11
+
12
+ - The generation command lives in the repo: an npm script, an MSBuild target, a `scripts/` file or the generator's own config file. Anyone can rerun it.
13
+ - Never edit generated files by hand. Change the input or the generator's config and regenerate.
14
+ - Pin the generator version in the repo's dev dependencies or tool manifest.
15
+ - Review the generated diff like any other diff, then run the build and tests.
16
+
17
+ ## OpenAPI clients
18
+
19
+ | Stack | Tool | Command |
20
+ |---|---|---|
21
+ | .NET | NSwag | `dotnet new tool-manifest` once, `dotnet tool install NSwag.ConsoleCore`, keep an `nswag.json`, then `DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet nswag run nswag.json` |
22
+ | .NET, TS, Python | Kiota | `KIOTA_CLI_TELEMETRY_OPTOUT=1 kiota generate -l CSharp -d openapi.yaml -o src/Client -n My.Client -c ApiClient` (`-l TypeScript`, `-l Python`) |
23
+ | TS, Python | openapi-generator | `npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g typescript-fetch -o src/client` (`-g python`); needs Java, and the first run downloads the generator jar |
24
+
25
+ Kiota sends usage telemetry unless `KIOTA_CLI_TELEMETRY_OPTOUT=1` is set; set it in the script, not only in your shell.
26
+
27
+ Windows PowerShell has no `NAME=value command` form: write the variable first in the same command, for example `$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1'; dotnet test`.
28
+
29
+ ## Codemods with ast-grep
30
+
31
+ ast-grep matches syntax, not text, so it does not touch strings or comments that merely look like code.
32
+
33
+ ```
34
+ ast-grep run --lang ts --pattern 'console.log($A)' --rewrite 'logger.debug($A)' # preview
35
+ ast-grep run --lang ts --pattern 'console.log($A)' --rewrite 'logger.debug($A)' --update-all
36
+ ```
37
+
38
+ For a change applied more than once, write a rule file and keep it in the repo (`sgconfig.yml` plus `rules/`), then `ast-grep scan --update-all`. Languages include C#, TypeScript, JavaScript and Python.
39
+
40
+ ## Scaffolding
41
+
42
+ Use the stack's own templates: `dotnet new <template>` (with `DOTNET_CLI_TELEMETRY_OPTOUT=1`), `npm create <template>`, or a template the repo already has. Do not invent a project layout the repo does not follow.
43
+
44
+ ## After generating
45
+
46
+ Then run the repository's own build and test commands (from its README, AGENTS.md or CI configuration) and `code-jig analyze --base main`, and report what changed, which generator or script made the change, and the build, test and analysis results.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: cross-review
3
+ description: Use when a plan, design, document or diff would benefit from a review by a model from a different family before it is committed, or when the user asks for a second opinion, a cross-model review or an adversarial review.
4
+ ---
5
+
6
+ # Cross-review
7
+
8
+ A reviewer from another model family catches different mistakes. The `review` tier is configured with one.
9
+
10
+ ## Run it
11
+
12
+ From the directory under review:
13
+
14
+ ```
15
+ code-jig cross-review # the working tree against HEAD
16
+ code-jig cross-review --base main # the branch against main
17
+ code-jig cross-review docs/plan.md # one or more files
18
+ ```
19
+
20
+ Run it from the repository under review with the installed launcher: `code-jig cross-review` (alias `cjig cross-review`; the URL bootstrap installs both). Untracked files are not part of a diff, so pass them as files. The command refuses input over 200,000 bytes; split the review instead.
21
+
22
+ The reviewer runs in an ephemeral session with a read-only sandbox, no command escalation and no web search, treats the material as untrusted data, and prints its findings.
23
+
24
+ ## Verify before acting
25
+
26
+ The findings are claims, not facts. For each one:
27
+
28
+ 1. Open the cited location and check the claim against the code or text.
29
+ 2. Classify it as `confirmed` (reproduced or clearly true), `plausible` (cannot be checked cheaply but holds up), or `rejected` (wrong, with the reason).
30
+ 3. Report confirmed and plausible findings with their location and fix. Give the rejected ones as a single line each, so the user can disagree.
31
+
32
+ Do not apply a fix only because the reviewer said so. A confirmed finding gets a failing test before the fix when the code has tests.
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: grilling
3
+ description: Use when the user wants a plan, decision, design or idea stress-tested before committing to it, or says "grill me", "grill this", "stress-test this", "poke holes in this", "what am I missing". Do not fire on your own.
4
+ ---
5
+
6
+ # Grilling
7
+
8
+ Run only when the user asks to be grilled or to stress-test something; never start a grilling on your own. Interview the user until you both understand the decision the same way. Map it as a design tree: every decision branches into the decisions that hang off it.
9
+
10
+ Work the tree in rounds. The frontier is every decision whose prerequisites are already settled, which are the questions you can ask now without guessing answers you have not heard. Ask the frontier at most three questions per round. Number each question, give the options, and give your recommendation. Then wait for the answers before the next round.
11
+
12
+ Nothing stays in the user's head between turns, so every round carries its own state.
13
+
14
+ ## Round format
15
+
16
+ ```
17
+ **Settled (N):** <one short clause per settled decision, most recent last>
18
+
19
+ **Round K. Frontier: <count>.**
20
+
21
+ **Q1 - <title>**: <question>
22
+
23
+ a) ... b) ... c) ...
24
+
25
+ Recommendation: <your answer, what you would reject and why, and context they may have forgotten>
26
+
27
+ **Deferred**: <titles of questions blocked on this round, or "none">
28
+ ```
29
+
30
+ Never skip the settled line or the deferred line, even in a one-question round. A question whose answer depends on another open question belongs to a later round. A frontier wider than three spills into the next round, and its titles go in the deferred list.
31
+
32
+ ## Skip
33
+
34
+ The user may answer `skip`. Take your recommendation, mark it `(assumed)`, and keep going. At the end, list every assumed answer once for a yes or no confirmation.
35
+
36
+ ## Facts are yours, decisions are theirs
37
+
38
+ When a question needs a fact from the environment (files, tools, docs, the web), find it yourself, with an `explorer` subagent when subagents are available. A web lookup from a sandbox without network needs an approved escalation; if it is refused, say the fact is unverified and ask the rest of the frontier. Never ask the user for something you can look up. Only questions that depend on a pending lookup wait for it; ask the rest of the frontier now. State the fact when you use it.
39
+
40
+ ## Tree file
41
+
42
+ Write `grill-<slug>.md` in the current workspace (never outside it, which the sandbox may refuse) and update it at the end of every round. In a read-only sandbox, keep the same structure in your reply instead:
43
+
44
+ ```markdown
45
+ # Grill: <topic>
46
+
47
+ ## Settled
48
+ - Q1 <title>: <answer> (over <rejected option>) - <one-line why>
49
+ - Q2 <title>: <answer> (assumed)
50
+
51
+ ## Open
52
+ - Frontier: <titles>
53
+ - Deferred: <titles>
54
+ ```
55
+
56
+ ## Ending
57
+
58
+ The session ends when the frontier is empty: every branch visited, nothing silently assumed. Confirm the assumed answers, then summarise the settled tree and ask whether to write it up as a spec or plan. Do not act on the outcome until the user confirms you agree.
59
+
60
+ These thoughts mean you are quitting early. Recompute the frontier and ask the next round instead: "the rest is implementation detail", "we can figure that out later", "the remaining questions are obvious", "good enough to start".
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: hld-trace
3
+ description: Use when the user asks whether the code follows the high-level design (HLD), which requirements have tests, which are untested, or wants tests linked to requirement or work item IDs.
4
+ ---
5
+
6
+ # HLD trace
7
+
8
+ Requirements get IDs, tests cite them, and `code-jig trace` checks the links deterministically. Judging whether a test really proves its requirement stays with you.
9
+
10
+ ## 1. Get the requirement IDs
11
+
12
+ Write them to a file, one per line, or as JSON (a list of IDs, or objects with an `id` field).
13
+
14
+ Before any `az` command below, check that `az` exists (`command -v az`; PowerShell: `Get-Command az`) and is logged in (`az account show`), that the `azure-devops` extension is there (`az extension show --name azure-devops`), and that defaults are set (`az devops configure --list`). Before any `gh` command, check `command -v gh` (PowerShell: `Get-Command gh`) and `gh auth status`. Logging in is interactive, so never run `az login` or `gh auth login` yourself: ask the user to run it in their own terminal, then check again. Ask before `az extension add --name azure-devops` and before `az devops configure --defaults organization=<url> project=<name>`.
15
+
16
+ - Azure DevOps work items (child items of a feature or epic):
17
+
18
+ ```
19
+ az boards query --wiql "SELECT [System.Id] FROM WorkItems WHERE [System.Parent] = 1234" -o json > ids.json
20
+ ```
21
+
22
+ - Azure DevOps wiki, when the HLD page lists IDs such as `REQ-12`:
23
+
24
+ ```
25
+ az devops wiki page show --wiki <wiki> --path "/Design/Login" --include-content --query page.content -o tsv > hld.md
26
+ grep -oE "REQ-[0-9]+" hld.md | sort -u > ids.txt
27
+ ```
28
+
29
+ PowerShell: `Select-String -Path hld.md -Pattern "REQ-\d+" -AllMatches | ForEach-Object { $_.Matches.Value } | Sort-Object -Unique > ids.txt`.
30
+
31
+ - GitHub issues: `gh issue list --label requirement --json number --jq ".[].number" > ids.txt` (`--jq` is built into `gh`, so the line is the same in PowerShell).
32
+ - A Markdown HLD in the repo: the same `grep` as the wiki case.
33
+
34
+ When `az` or `gh` is missing, or the user cannot log in, do not install anything: ask the user to paste the IDs or export the page (a work item query saved as CSV or JSON, the wiki page as Markdown, `gh issue list` output), and turn it into the ID file above before tracing: a CSV export becomes one ID per line with `python3 -c "import csv,sys; [print(r['ID']) for r in csv.DictReader(open(sys.argv[1], encoding='utf-8-sig'))]" export.csv > ids.txt` (PowerShell: `Import-Csv export.csv | ForEach-Object { $_.ID } > ids.txt`), using the export's ID column name; Markdown gets the same `grep` as the wiki case.
35
+
36
+ ## 2. Tag the tests
37
+
38
+ For each requirement, search the test files for the names it uses (endpoint, function, field, error message) with `rg -i` (`grep -rni` where `rg` is missing; PowerShell: `Select-String`), read the matching tests, and add the requirement's tag to those whose assertions check it, in the form the framework below uses; tests written in step 4 get the tag as they are written. Default tag: `REQ-<id>`, anywhere in a test file, case-insensitive.
39
+
40
+ | Framework | Example |
41
+ |---|---|
42
+ | xUnit | `[Trait("Requirement", "REQ-1234")]` |
43
+ | NUnit | `[Property("Requirement", "REQ-1234")]` |
44
+ | MSTest | `[TestProperty("Requirement", "REQ-1234")]` |
45
+ | Jest, Vitest | `it("REQ-1234 rejects an expired token", ...)` |
46
+ | pytest | `@pytest.mark.req("REQ-1234")`, with the `req` marker registered in the pytest config |
47
+
48
+ Teams that already write Azure Boards links in tests can keep them: `--pattern "AB#{id}"`. The pattern is literal text with one `{id}` placeholder.
49
+
50
+ ## 3. Run the trace
51
+
52
+ ```
53
+ code-jig trace ids.txt # or ids.json, or - for stdin
54
+ code-jig trace ids.txt --path services/api
55
+ code-jig trace ids.txt --pattern "AB#{id}" --json
56
+ ```
57
+
58
+ It reads test files that git tracks or would track (`tests/`, `__tests__/`, `*.test.ts`, `test_*.py`, `*Tests.cs`, `*.Tests/` projects and similar) and reports requirements with tests, `missing` requirements, and `unknown` IDs that tests cite but the list does not contain. Exit 0 when nothing is missing or unknown, 1 otherwise, 2 for unusable input.
59
+
60
+ ## 4. Close the gaps
61
+
62
+ - Missing: write the test (the `regression-tests` skill), tagged.
63
+ - Unknown: the requirement was renamed or removed, or the tag has a typo. Ask before deleting a test.
64
+ - Covered: read each requirement next to its tests and confirm the assertions prove it. A tag on a test that checks something else is worse than no tag.
65
+ - After changing any test or tag, rerun step 3 so the report uses current results.
66
+
67
+ ## 5. Report
68
+
69
+ One table: each requirement ID, `covered`, `missing` or `unknown`, the test files that cite it, and for covered ones whether the assertions prove it. List the tests tagged, the tests written, and any deletion still waiting for the user. Commit nothing; the user reviews the diff.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: improve
3
+ description: Use when the user asks to improve code-jig, its rules, Guardian policy, skills or knowledge from experience on this machine, or says "remember this for next time", "make this a rule", "teach code-jig", "teach the harness".
4
+ ---
5
+
6
+ # Improve
7
+
8
+ Turn something learned into a durable change, in the right place, without leaking what must stay local.
9
+
10
+ ## Start
11
+
12
+ 1. Run `code-jig doctor` and fix any FAIL first.
13
+ 2. Read `overlay.toml` in the overlay (`$CODE_JIG_OVERLAY`, in PowerShell `$env:CODE_JIG_OVERLAY`, or the path the user gives). `core_writable` decides where you may write.
14
+
15
+ ## Where changes go
16
+
17
+ | Change | Slot |
18
+ |---|---|
19
+ | A rule every session should follow | `AGENTS.overlay.md` |
20
+ | Something Guardian should treat as riskier or safer | `guardian-policy.md` (additions to the upstream policy, never a replacement) |
21
+ | A model for a tier | `profiles.toml` |
22
+ | A command rule | `rules/<name>.rules`. Prefer `forbidden` rules. An `allow` rule runs the command outside the sandbox with no review, and the agent can change what a test or build command runs, so allow only what you would run unsupervised in that repo. |
23
+ | A repeatable workflow | `skills/<name>/SKILL.md`, then run the `skill-validate` skill on it |
24
+ | A fact about tools, services or conventions here | `knowledge/<slug>.md`, one fact per file, plus one line in `knowledge/INDEX.md` |
25
+
26
+ With `core_writable = false`, write only to these overlay slots. Never edit the core checkout. With `core_writable = true` (a bench machine), core edits are allowed, with tests, and are committed in the core repo.
27
+
28
+ ## Knowledge
29
+
30
+ - One fact per file: what is true, why it matters, how to apply it.
31
+ - Before adding, search the index for a file that already covers it, and update that file instead.
32
+ - Keep `INDEX.md` at 150 lines or fewer, one line each. Merge related facts. When a fact is no longer true, name the file to the user and delete it only after they agree.
33
+
34
+ ## Finish
35
+
36
+ 1. Run `code-jig install`, then `code-jig doctor`.
37
+ 2. Summarise what changed and where.
38
+ 3. End with **Upstream candidates**: improvements that would help anyone, written in generic language. Leave out company and product names, hosts, people, numbers measured at work, and code copied from work. The user decides whether to restate them on another machine. Nothing is copied across.
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: redacao
3
+ description: Use when writing, rewriting or editing a technical article or blog post in Portuguese, or when the user says "escreve um artigo", "reescreve o post", "redação", "pauta", "revisa o texto", "tira a cara de IA".
4
+ ---
5
+
6
+ # Redação
7
+
8
+ You are the reporter. The user is the editor of the newsroom (editor da redação). Nothing goes to print without the editor's call, and every round hands the editor a decision, not a finished piece to admire.
9
+
10
+ The editor is also the author. The opinions, the scenes, the doubts and the register come from them; the facts come from your apuração. A draft built only from facts reads as a changelog narrated by nobody, and readers notice in the first paragraph. When a section needs something only the author knows, ask. Never invent a feeling, a habit or a reason for them.
11
+
12
+ Output in Brazilian Portuguese. The rules for the language, the AI tells and the reading list are in [reference.md](reference.md). Read it before the first draft.
13
+
14
+ ## Hard rules
15
+
16
+ - No fact without a source. Every number, version, file name and claim comes from a command you ran, a file you read or a URL you opened. Write it to the fact sheet before it enters the text. A fact you could not check is cut or flagged to the editor, never softened into a vague sentence.
17
+ - Never commit or `git add` the article. The editor publishes. Code examples, configs and fixes found along the way follow the repo's normal rules.
18
+ - Voice comes from the author's own text, in this order: a style guide the author keeps, when one exists (for example one generated by a `style-guide` skill installed on this machine; ask where it is, never invent one), then the entrevista answers, then anything the author wrote by hand (an earlier version of the article in git history, a vault note). On voice and style it wins over reference.md; the rules in this file and the checks in reference.md still apply. Never fall back to your default voice.
19
+ - Text an AI wrote (old drafts, vault notes, specs, an earlier version of the post) is a source of facts and links only. Re-check every fact you take from it and never reuse its sentences, headings or structure: that is how the old voice leaks back in.
20
+ - Personal details (health, family, money) enter only when the author wrote them for this article, even if the vault has more.
21
+ - A published version the author approved is the base of any rewrite. Keep its text and change only what the new angle needs; list every change in `Mudanças`. A rewrite from zero replaces their approved voice with yours. This holds even when an AI wrote that version: the author's approval made it their text, so the rule above about AI text covers only drafts and notes they never approved.
22
+ - The author's idea sets the scope. When the apuração turns up a better story, it goes to `Fica de fora` as its own pauta; it does not take over this article.
23
+ - Never present the AI tells checklist as a detector. It is a list of habits that make prose worse, whoever wrote it.
24
+
25
+ ## 1. Entrevista
26
+
27
+ Before the apuração, ask the author up to six questions, in one message:
28
+
29
+ 1. Why this article, and why now?
30
+ 2. The moment that made you want to write it: what happened, where you were, what you did next.
31
+ 3. What do you think about it that most people get wrong?
32
+ 4. What surprised, annoyed or embarrassed you along the way?
33
+ 5. What are you still unsure about?
34
+ 6. If an earlier draft or note exists, which part of it still sounds like you?
35
+
36
+ Ask for answers typed fast or dictated, without revising; typos stay. Save them verbatim in `entrevista-<slug>.md`. These answers are the raw material: keep their words, their order and their slang in the text, and take the tese from them. If the author declines, use their hand-written text from the voice list above and say so in the pauta.
37
+
38
+ When the author hands raw text instead, it is the spine of the article. Keep their sentences and their order; fix only spelling, agreement and punctuation, and list every fix in `Mudanças`. Build the rest around it from facts. Every bridging sentence they did not write is marked `⚠` in the draft until they confirm, rewrite or cut it. If they also ask for the full piece, the pauta still comes first: present it and wait for `aprova`, then write every section in one draft and run the next rounds on that draft instead of section by section.
39
+
40
+ ## 2. Apuração
41
+
42
+ Before writing a word, gather the facts yourself. Read the code, run the tests, the build and the linters, read the git log and any specs. Measure the published state, not a dirty working tree: find the published commit first (the release tag, or `git rev-parse '@{upstream}'` for what was pushed; the quotes keep PowerShell from reading the braces; ask the author when neither says what is live), then measure in a detached worktree of that commit (`git worktree add --detach <dir> <commit>`). Do not delete it yourself: in the final report, give its path and the `git worktree remove <dir>` line for the editor.
43
+
44
+ Write `apuracao-<slug>.md` in the workspace: one line per fact, with its source (`command`, `path:line` or URL). Mark the gaps and the things that contradict the story you expected. Those are often the best material.
45
+
46
+ For links, start from the links in the currently published version of the article (commits, issues, the articles that motivated it), then what the project actually used: the specs, design docs and READMEs behind it. Prefer a GitHub commit, issue or file that shows the thing over a sentence describing it. Open every URL before citing it and quote what it says in the fact sheet. A link earns its place by backing a sentence the reader cares about.
47
+
48
+ The fact sheet is a quarry, not the outline. Most facts stay out of the text. A fact enters when the story needs it at that point, not because it was checked.
49
+
50
+ `explorer` subagents may gather, but verify anything they report that goes into the text. They summarise confidently and get file states wrong.
51
+
52
+ ## 3. Pauta
53
+
54
+ The first round is the pitch. Present:
55
+
56
+ ```
57
+ **Pauta: <working title>**
58
+
59
+ Leitor: <who reads this and what they already know>
60
+ Tese: <one sentence the article proves, in the author's words from the entrevista>
61
+ Tamanho: <target word count; a personal post rarely needs more than 1,200>
62
+ Gancho: <the concrete fact or scene that opens it>
63
+ Seções:
64
+ 1. <heading> - <what it shows, in one line>
65
+ 2. ...
66
+ Fica de fora: <what you will not cover and why>
67
+ Fontes: <the strongest three facts from the apuração>
68
+ Destino: <the file the final article goes to; ask the editor when the repo does not make it obvious>
69
+
70
+ ❓ **Decisões** (at most 3, numbered, each with options a/b/c and your recommendation)
71
+ ```
72
+
73
+ Wait for the editor. Do not draft sections before the pauta is approved.
74
+
75
+ ## 4. Rodadas
76
+
77
+ Draft one section per round, two if both are short. Each round:
78
+
79
+ ```
80
+ **Fechado (N):** <one clause per approved section or decision, latest last>
81
+
82
+ **Rodada K: <section heading>**
83
+
84
+ <the section, final prose, one paragraph per line>
85
+
86
+ **Mudanças**
87
+ - "<old fragment>" → "<new fragment>": <why, in a few words>
88
+ (on a rewrite, compare against the original text; on a first draft, list the choices a reader would question)
89
+
90
+ **Checagem:** <facts used in this section and their sources from the apuração>
91
+
92
+ **Do autor:** <what in this section came from the entrevista or the author's own text; if nothing did, ask a question instead of shipping the section>
93
+
94
+ ❓ **Decisões** (at most 3, with options and your recommendation)
95
+
96
+ **Na fila:** <headings still to write>
97
+ ```
98
+
99
+ The editor answers per section: `aprova`, `corta <trecho>`, `reescreve <instrução>`, or a question. A `aprova` moves the section to Fechado. Anything else is the next round for the same section. The editor may answer `pula` to a decision: take your recommendation, mark it `(assumido)`, and list every assumed decision once before closing.
100
+
101
+ Keep the state in `redacao-<slug>.md` next to the fact sheet and update it every round: approved text, open decisions, the queue. Nothing lives in the editor's head between turns.
102
+
103
+ ## 5. Fechamento
104
+
105
+ When every section is approved:
106
+
107
+ 1. Assemble the full text and save it as `rascunho-<slug>.md` in the workspace. Write the title, the description (frontmatter) and the first paragraph last, now that you know what the article proves.
108
+ 2. Run `python3 "<skill dir>/checar.py" rascunho-<slug>.md` (Windows: `py -3 "<skill dir>\checar.py" rascunho-<slug>.md`); `<skill dir>` is the folder this SKILL.md is in. LanguageTool is optional: it runs as a local server, and without one the script still prints the rhythm numbers. It prints the rhythm numbers and the LanguageTool pt-BR matches; it starts nothing, and tells you the `podman run` line when LanguageTool is down. Fix real spelling, agreement and crase errors. Ignore matches on English technical terms, and never take a suggestion that flattens the author's register. LanguageTool misses agreement errors ("nossas vida"), so it is not a substitute for reading. Then run the checklist in reference.md over the whole text. Read it aloud in your head; a sentence you would not say to a colleague gets rewritten.
109
+ 3. Present the full text with a final `Mudanças` list for anything the assembly changed, then ask for the last `aprova`.
110
+ 4. After approval, write it to the `Destino` file from the approved pauta. Do not commit it. Say where it is and what the editor still has to do (translation, images, publishing).
111
+
112
+ ## Quitting early
113
+
114
+ These thoughts mean you are skipping the editor. Stop and run the round instead: "the editor will like this, I'll do the next three sections", "this change is too small to list", "the pauta is obvious", "I'll fix the facts at the end", "I can write the author's opinion for them", "every checked fact deserves a place".