great-cto 3.74.0 → 3.75.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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "great-cto",
|
|
3
3
|
"description": "You already have the agent. This is everything around it. great_cto runs Claude Code as a pipeline of 72 specialist agents \u2014 an independent model checks each stage before the next builds on it, spending caps refuse rather than warn, and three decisions stay yours: what gets built, how, and whether it ships.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.75.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexander Velikiy",
|
|
7
7
|
"url": "https://hashnode.com/@Greatcto"
|
|
@@ -92,8 +92,9 @@ snapshots, binaries) are excluded, because their size is not review effort.
|
|
|
92
92
|
3. **Performance** — needless O(n²), N+1 queries, unbounded growth, sync work on a
|
|
93
93
|
hot path, missing pagination/limits. Only when it matters at realistic scale.
|
|
94
94
|
4. **Readability / maintainability** — naming, dead code, duplicated logic,
|
|
95
|
-
missing tests for new behaviour,
|
|
96
|
-
|
|
95
|
+
missing tests for new behaviour, a test an empty body would satisfy (it still
|
|
96
|
+
passes if the function under test does nothing, so it asserts nothing), comments
|
|
97
|
+
that lie, an abstraction that hides a bug. Match the surrounding code's idiom.
|
|
97
98
|
|
|
98
99
|
## Calibration — apply `shared/agent-fragments/argument-quality.md`
|
|
99
100
|
|
|
@@ -227,7 +227,9 @@ Runs all of Phase 4 (sections labeled in stdout):
|
|
|
227
227
|
- **4A.0** intersects the top-20 largest source files with the top-20 most-git-churned files
|
|
228
228
|
(last 6 months), writing scratch files to `/tmp/audit-{largest,churn,hotspots}.txt`. Every
|
|
229
229
|
file in the intersection MUST receive concrete file:line citations in the findings table —
|
|
230
|
-
these are the most expensive places to leave debt unaddressed.
|
|
230
|
+
these are the most expensive places to leave debt unaddressed. A hotspot with no test
|
|
231
|
+
beside it gets "characterize before change" in its Recommendation: the first edit there
|
|
232
|
+
should be a test pinning its current behaviour.
|
|
231
233
|
- **4A** code structure signals — god files (>500 lines), circular-import risk count,
|
|
232
234
|
dead-code marker count (TODO/FIXME/HACK/XXX/DEPRECATED), duplicated-basename files.
|
|
233
235
|
- **4B** infrastructure & ops debt — Docker base image lines, k8s/Helm apiVersion usage,
|
|
@@ -611,6 +611,11 @@ asserts nothing. Mutation testing closes that — it introduces small faults
|
|
|
611
611
|
(flip a comparison, drop a call, change a boundary) and reports how many the
|
|
612
612
|
suite **catches**. A surviving mutant is a fault your tests would have shipped.
|
|
613
613
|
|
|
614
|
+
Small tasks skip the run, not the question: the cheap form is the empty-implementation
|
|
615
|
+
check — stub the function under test to do nothing; a test that still passes asserts
|
|
616
|
+
nothing. senior-dev runs it at RED and code-reviewer flags it; if you see such a test
|
|
617
|
+
in a small task, report it.
|
|
618
|
+
|
|
614
619
|
Run it on the **changed files only** — a full-repo mutation run is minutes-to-hours
|
|
615
620
|
and mostly re-verifies untouched code:
|
|
616
621
|
|
|
@@ -73,7 +73,8 @@ that get pushed back on, because those are the ones nobody else will catch.
|
|
|
73
73
|
projects measured on 2026-09-21, 1,181 of 5,126 operator messages were "делай" /
|
|
74
74
|
"да" answering exactly that question.
|
|
75
75
|
- the next step of a plan that already passed `gate:plan`;
|
|
76
|
-
- re-running a check after a fix, until it is green or the failure is understood
|
|
76
|
+
- re-running a check after a fix, until it is green or the failure is understood (two failed
|
|
77
|
+
fixes on one assumption end that loop — see "Two fixes, one premise", step 5).
|
|
77
78
|
|
|
78
79
|
This list does not replace **Ask before proceeding** above: a lint rule to disable, a
|
|
79
80
|
pattern to copy, an "unrelated" failing test, a field added to an API, an empty
|
|
@@ -475,6 +476,11 @@ Schema: `skills/great_cto/references/knowledge-extraction.md`
|
|
|
475
476
|
- If `data-platform` archetype → dbt tests + data contract validation / snapshot regression
|
|
476
477
|
- If `ai-system` archetype → evals-first (write eval suite before any prompt/model changes)
|
|
477
478
|
- All other archetypes → standard TDD (follow `superpowers:test-driven-development`):
|
|
479
|
+
- **Characterize first** — if the code you must change has no test covering it, write
|
|
480
|
+
a test that pins what it does TODAY (a golden/snapshot of current output is enough; it
|
|
481
|
+
records behaviour, not a verdict on it) and see it **pass on the unchanged code**. This
|
|
482
|
+
is the one test meant to pass before the change. Then change under RED/GREEN; when the
|
|
483
|
+
change alters the pinned output, update the pin deliberately and say so.
|
|
478
484
|
- **RED**: write failing test, then **explicitly verify it fails**:
|
|
479
485
|
```bash
|
|
480
486
|
npm test -- --testPathPattern="<new-test>" 2>&1 | grep -E "FAIL|PASS|Error" | head -5
|
|
@@ -488,9 +494,23 @@ Schema: `skills/great_cto/references/knowledge-extraction.md`
|
|
|
488
494
|
PYTHONUNBUFFERED=1 pytest ... > /tmp/test-out.log 2>&1 &
|
|
489
495
|
sleep 2; tail -f /tmp/test-out.log # then Ctrl-C when done
|
|
490
496
|
```
|
|
491
|
-
If test PASSES before implementation → the test is wrong. Fix it first.
|
|
497
|
+
If test PASSES before implementation → the test is wrong. Fix it first. (The one
|
|
498
|
+
exception is the characterization pin above, which must pass on unchanged code.)
|
|
499
|
+
- **Stub check — before GREEN, even when RED is already confirmed.** A RED that failed
|
|
500
|
+
because the function does not exist ("not defined", an import error) says nothing about
|
|
501
|
+
the assertions. So create the stub (empty body: returns nothing, does nothing) and run
|
|
502
|
+
the new tests against it, then say in your reply which of them still pass. "Not
|
|
503
|
+
called", "does not throw" and "is defined" assertions all pass against it; a suite made
|
|
504
|
+
of them asserts nothing, so add the test for the positive effect (the call made, the
|
|
505
|
+
value returned) until the stub fails on an assertion. Mutation testing is skipped for
|
|
506
|
+
small tasks; this check is not.
|
|
492
507
|
- **GREEN**: write minimal code to make test pass → re-run → confirm PASS
|
|
493
508
|
- **REFACTOR**: clean up → confirm still PASS, no coverage regression
|
|
509
|
+
- **Two fixes, one premise → stop.** When two fixes resting on the same assumption have
|
|
510
|
+
failed the same check, write that assumption in one sentence and make no third edit on
|
|
511
|
+
it. Test the assumption itself first (print the value, query the real dependency, run
|
|
512
|
+
the one-line repro); if it is false, redesign from what you found, and if you cannot
|
|
513
|
+
test it, escalate. A third try on the same idea is a coin toss, not a fix.
|
|
494
514
|
6. **Quality check**: all tests pass, no lint errors, coverage ≥80%, no hardcoded secrets
|
|
495
515
|
6b. **Scope check against the IMPL-BRIEF** (governance Phase 3 — before staging):
|
|
496
516
|
```bash
|
|
@@ -34,7 +34,17 @@ import { fileURLToPath } from 'node:url';
|
|
|
34
34
|
|
|
35
35
|
const sha = (s) => createHash('sha256').update(String(s)).digest('hex');
|
|
36
36
|
|
|
37
|
+
// Hooks read evidence under host deadlines of 5-15 s and must give up in time to
|
|
38
|
+
// fail closed themselves, so 5 s is the default. A long-lived caller on a loaded
|
|
39
|
+
// machine (the packaged controller probe) widens it with
|
|
40
|
+
// GREAT_CTO_GIT_READ_TIMEOUT_MS; it never narrows below 5 s nor passes 120 s.
|
|
41
|
+
export const GIT_READ_TIMEOUT_MS = 5000;
|
|
42
|
+
export function gitReadTimeoutMs(raw = process.env.GREAT_CTO_GIT_READ_TIMEOUT_MS) {
|
|
43
|
+
return /^\d{1,9}$/.test(raw ?? '') ? Math.min(Math.max(Number(raw), GIT_READ_TIMEOUT_MS), 120000) : GIT_READ_TIMEOUT_MS;
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
function git(args, cwd, { maxBuffer = 32 * 1024 * 1024 } = {}) {
|
|
47
|
+
const timeout = gitReadTimeoutMs();
|
|
38
48
|
try {
|
|
39
49
|
// Reading evidence must not execute project-configured diff/filter/monitor helpers.
|
|
40
50
|
const command = args[0] === 'diff' ? ['diff', '--no-ext-diff', '--no-textconv', ...args.slice(1)] : args;
|
|
@@ -45,14 +55,14 @@ function git(args, cwd, { maxBuffer = 32 * 1024 * 1024 } = {}) {
|
|
|
45
55
|
let keys = '';
|
|
46
56
|
try {
|
|
47
57
|
keys = execFileSync('git', [...config, 'config', '--null', '--name-only', '--get-regexp', '^filter\\..*\\.(clean|process|required)$'],
|
|
48
|
-
{ cwd, encoding: 'utf8', maxBuffer: 65536, timeout
|
|
58
|
+
{ cwd, encoding: 'utf8', maxBuffer: 65536, timeout, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
49
59
|
} catch (error) { if (error.status !== 1) return null; }
|
|
50
60
|
const filters = [...new Set(keys.split('\0').filter(Boolean).map(key => key.match(/^filter\.([\s\S]+)\.(?:clean|process|required)$/)?.[1]))];
|
|
51
61
|
if (filters.length > 128 || filters.some(name => !name)) return null;
|
|
52
62
|
for (const name of filters) config.push('-c', `filter.${name}.clean=`, '-c', `filter.${name}.process=`, '-c', `filter.${name}.required=false`);
|
|
53
63
|
}
|
|
54
64
|
return execFileSync('git', [...config, ...command],
|
|
55
|
-
{ cwd, encoding: 'utf8', maxBuffer, timeout
|
|
65
|
+
{ cwd, encoding: 'utf8', maxBuffer, timeout, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
56
66
|
} catch { return null; }
|
|
57
67
|
}
|
|
58
68
|
|
package/package.json
CHANGED