@olegkoval/agent-skills 1.41.1 → 1.41.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +50 -37
- package/package.json +1 -1
- package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +50 -37
- package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
|
@@ -41,9 +41,17 @@ function liftConst(name) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const preamble = [
|
|
44
|
-
|
|
44
|
+
// HARD_RULES is absent from the current workflow.js: the allowlist went away
|
|
45
|
+
// with the exemption it gated. It is still lifted-with-a-fallback rather than
|
|
46
|
+
// dropped, because this suite must stay runnable against an OLDER workflow.js
|
|
47
|
+
// (see the target argument above) to prove it discriminates. Without the
|
|
48
|
+
// fallback the old file throws ReferenceError instead of reporting FAIL, and a
|
|
49
|
+
// suite that crashes on the pre-fix input has proved nothing.
|
|
50
|
+
(() => { try { return liftConst('HARD_RULES') } catch { return 'const HARD_RULES = []' } })(),
|
|
45
51
|
(() => { try { return liftConst('SAME_ISSUE_LINE_WINDOW') } catch { return 'const SAME_ISSUE_LINE_WINDOW = 30' } })(),
|
|
46
52
|
"const SEVERITY_RANK = { observation: 0, idiomatic: 1, important: 2, critical: 3 }",
|
|
53
|
+
// hardRuleCorroborated is likewise gone from the current file and kept in this
|
|
54
|
+
// list for the same reason: an older workflow.js calls it from isHardRule.
|
|
47
55
|
...['titleTokens', 'sameIssue', 'nearbyLines', 'spanWithinWindow', 'hardRuleCorroborated',
|
|
48
56
|
'isHardRule', 'longest', 'mergeFindings', 'dedup', 'shouldVerify'].map(n => {
|
|
49
57
|
try { return lift(n) } catch { return `function ${n}() { throw new Error('${n} absent from this workflow.js') }` }
|
|
@@ -98,46 +106,51 @@ check('different files never merge', dedup([
|
|
|
98
106
|
{ file: 'b.ts', line: 7, severity: 'critical', title: 'Off-by-one loop skips the first line', badCode: '', description: '' },
|
|
99
107
|
]).length, 2)
|
|
100
108
|
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
// This section used to assert that a `rule` tag had to be corroborated against a
|
|
110
|
+
// hardcoded HARD_RULES list before it could SKIP verification. That guard existed
|
|
111
|
+
// because a fabricated tag could buy exemption. It is gone because the exemption
|
|
112
|
+
// is gone: shouldVerify now returns true for every Critical and Important finding,
|
|
113
|
+
// and a hard rule takes the verifier's rule-specific anchor and applicability path
|
|
114
|
+
// instead of its runtime challenges, validated against the configured canonical
|
|
115
|
+
// rules file. A hardcoded list also could not recognise a custom house rule, which
|
|
116
|
+
// the current design supports on purpose.
|
|
117
|
+
//
|
|
118
|
+
// So the tag no longer buys a free pass; it selects a verification path. The
|
|
119
|
+
// predicate is correspondingly narrow: does this finding claim a rule at all.
|
|
120
|
+
console.log('\nhard rules: the tag selects a verification path, it does not skip one')
|
|
121
|
+
// Regression, still worth holding: a finding with no rule tag must never be
|
|
122
|
+
// treated as one. That is what routes it to the runtime challenges.
|
|
123
|
+
check('no rule tag is not a hard rule',
|
|
124
|
+
isHardRule({ file: 'a.ts', line: 1, title: 't', badCode: 'x as Foo', description: '' }), false)
|
|
125
|
+
check('an empty rule tag is not a hard rule',
|
|
126
|
+
isHardRule({ rule: '', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
127
|
+
check('a whitespace-only rule tag is not a hard rule',
|
|
128
|
+
isHardRule({ rule: ' ', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
129
|
+
check('a non-string rule tag is not a hard rule',
|
|
130
|
+
isHardRule({ rule: 1, file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
115
131
|
|
|
116
|
-
console.log('\nhard rules:
|
|
117
|
-
|
|
118
|
-
check(
|
|
119
|
-
|
|
120
|
-
check('GQL-1 with a nodes query',isHardRule({ rule: 'GQL-1', file: 'q.graphql', line: 1, title: 'no pageInfo', badCode: 'products { nodes { id } }', description: '' }), true)
|
|
121
|
-
check('PR-1 anchored on the PR title', isHardRule({ rule: 'PR-1', file: 'PR title', line: 1, title: 'missing prefix', badCode: '', description: '' }), true)
|
|
122
|
-
// A cast to a lowercase built-in is as much a TS-1 violation as a cast to a
|
|
123
|
-
// named type. Missing it sent a genuine hard rule to a verifier that cannot
|
|
124
|
-
// answer a policy claim, where it could be dropped.
|
|
125
|
-
for (const cast of ['x as string', 'x as number', 'x as unknown as Foo', 'x as const', 'x as boolean']) {
|
|
126
|
-
check(`TS-1 corroborated by \`${cast}\``,
|
|
127
|
-
isHardRule({ rule: 'TS-1', file: 'a.ts', line: 1, title: 'cast', badCode: cast, description: '' }), true)
|
|
132
|
+
console.log('\nhard rules: built-in and custom tags both route to rule-specific verification')
|
|
133
|
+
for (const rule of ['TS-1', 'TS-2', 'GQL-1', 'PR-1']) {
|
|
134
|
+
check(`built-in ${rule} is a hard rule`,
|
|
135
|
+
isHardRule({ rule, file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), true)
|
|
128
136
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
// A house rule defined in the operator's canonical rules file cannot be known to
|
|
138
|
+
// this workflow. Rejecting it here is what a hardcoded list did, and it silently
|
|
139
|
+
// disabled every custom rule a deployment configured.
|
|
140
|
+
check('a custom house rule is a hard rule',
|
|
141
|
+
isHardRule({ rule: 'SEC-1', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), true)
|
|
133
142
|
|
|
134
|
-
console.log('\nverification scope
|
|
143
|
+
console.log('\nverification scope: depth controls breadth, never the trust bar')
|
|
135
144
|
const crit = { severity: 'critical' }, imp = { severity: 'important' }, obs = { severity: 'observation' }
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
check('
|
|
139
|
-
check('
|
|
140
|
-
|
|
145
|
+
// shouldVerify takes one argument now. Depth used to be able to switch verification
|
|
146
|
+
// off entirely, which meant a scan-depth review shipped unverified Criticals.
|
|
147
|
+
check('shouldVerify takes the finding alone', shouldVerify.length, 1)
|
|
148
|
+
check('critical and important are verified, observation is not',
|
|
149
|
+
[crit, imp, obs].map(f => shouldVerify(f)), [true, true, false])
|
|
150
|
+
check('a hard rule is NOT exempt from verification',
|
|
151
|
+
shouldVerify({ severity: 'critical', rule: 'TS-2', file: 'x.js', badCode: '', description: '', title: '' }), true)
|
|
152
|
+
check('a custom hard rule is NOT exempt either',
|
|
153
|
+
shouldVerify({ severity: 'critical', rule: 'SEC-1', file: 'x.ts', badCode: '', description: '', title: '' }), true)
|
|
141
154
|
|
|
142
155
|
// Per-host model routing is optional: a deployment may pin models per host via
|
|
143
156
|
// a MODEL_TABLE, or leave every agent() call to name its own model. Test it
|
package/package.json
CHANGED
|
@@ -41,9 +41,17 @@ function liftConst(name) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const preamble = [
|
|
44
|
-
|
|
44
|
+
// HARD_RULES is absent from the current workflow.js: the allowlist went away
|
|
45
|
+
// with the exemption it gated. It is still lifted-with-a-fallback rather than
|
|
46
|
+
// dropped, because this suite must stay runnable against an OLDER workflow.js
|
|
47
|
+
// (see the target argument above) to prove it discriminates. Without the
|
|
48
|
+
// fallback the old file throws ReferenceError instead of reporting FAIL, and a
|
|
49
|
+
// suite that crashes on the pre-fix input has proved nothing.
|
|
50
|
+
(() => { try { return liftConst('HARD_RULES') } catch { return 'const HARD_RULES = []' } })(),
|
|
45
51
|
(() => { try { return liftConst('SAME_ISSUE_LINE_WINDOW') } catch { return 'const SAME_ISSUE_LINE_WINDOW = 30' } })(),
|
|
46
52
|
"const SEVERITY_RANK = { observation: 0, idiomatic: 1, important: 2, critical: 3 }",
|
|
53
|
+
// hardRuleCorroborated is likewise gone from the current file and kept in this
|
|
54
|
+
// list for the same reason: an older workflow.js calls it from isHardRule.
|
|
47
55
|
...['titleTokens', 'sameIssue', 'nearbyLines', 'spanWithinWindow', 'hardRuleCorroborated',
|
|
48
56
|
'isHardRule', 'longest', 'mergeFindings', 'dedup', 'shouldVerify'].map(n => {
|
|
49
57
|
try { return lift(n) } catch { return `function ${n}() { throw new Error('${n} absent from this workflow.js') }` }
|
|
@@ -98,46 +106,51 @@ check('different files never merge', dedup([
|
|
|
98
106
|
{ file: 'b.ts', line: 7, severity: 'critical', title: 'Off-by-one loop skips the first line', badCode: '', description: '' },
|
|
99
107
|
]).length, 2)
|
|
100
108
|
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
// This section used to assert that a `rule` tag had to be corroborated against a
|
|
110
|
+
// hardcoded HARD_RULES list before it could SKIP verification. That guard existed
|
|
111
|
+
// because a fabricated tag could buy exemption. It is gone because the exemption
|
|
112
|
+
// is gone: shouldVerify now returns true for every Critical and Important finding,
|
|
113
|
+
// and a hard rule takes the verifier's rule-specific anchor and applicability path
|
|
114
|
+
// instead of its runtime challenges, validated against the configured canonical
|
|
115
|
+
// rules file. A hardcoded list also could not recognise a custom house rule, which
|
|
116
|
+
// the current design supports on purpose.
|
|
117
|
+
//
|
|
118
|
+
// So the tag no longer buys a free pass; it selects a verification path. The
|
|
119
|
+
// predicate is correspondingly narrow: does this finding claim a rule at all.
|
|
120
|
+
console.log('\nhard rules: the tag selects a verification path, it does not skip one')
|
|
121
|
+
// Regression, still worth holding: a finding with no rule tag must never be
|
|
122
|
+
// treated as one. That is what routes it to the runtime challenges.
|
|
123
|
+
check('no rule tag is not a hard rule',
|
|
124
|
+
isHardRule({ file: 'a.ts', line: 1, title: 't', badCode: 'x as Foo', description: '' }), false)
|
|
125
|
+
check('an empty rule tag is not a hard rule',
|
|
126
|
+
isHardRule({ rule: '', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
127
|
+
check('a whitespace-only rule tag is not a hard rule',
|
|
128
|
+
isHardRule({ rule: ' ', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
129
|
+
check('a non-string rule tag is not a hard rule',
|
|
130
|
+
isHardRule({ rule: 1, file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), false)
|
|
115
131
|
|
|
116
|
-
console.log('\nhard rules:
|
|
117
|
-
|
|
118
|
-
check(
|
|
119
|
-
|
|
120
|
-
check('GQL-1 with a nodes query',isHardRule({ rule: 'GQL-1', file: 'q.graphql', line: 1, title: 'no pageInfo', badCode: 'products { nodes { id } }', description: '' }), true)
|
|
121
|
-
check('PR-1 anchored on the PR title', isHardRule({ rule: 'PR-1', file: 'PR title', line: 1, title: 'missing prefix', badCode: '', description: '' }), true)
|
|
122
|
-
// A cast to a lowercase built-in is as much a TS-1 violation as a cast to a
|
|
123
|
-
// named type. Missing it sent a genuine hard rule to a verifier that cannot
|
|
124
|
-
// answer a policy claim, where it could be dropped.
|
|
125
|
-
for (const cast of ['x as string', 'x as number', 'x as unknown as Foo', 'x as const', 'x as boolean']) {
|
|
126
|
-
check(`TS-1 corroborated by \`${cast}\``,
|
|
127
|
-
isHardRule({ rule: 'TS-1', file: 'a.ts', line: 1, title: 'cast', badCode: cast, description: '' }), true)
|
|
132
|
+
console.log('\nhard rules: built-in and custom tags both route to rule-specific verification')
|
|
133
|
+
for (const rule of ['TS-1', 'TS-2', 'GQL-1', 'PR-1']) {
|
|
134
|
+
check(`built-in ${rule} is a hard rule`,
|
|
135
|
+
isHardRule({ rule, file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), true)
|
|
128
136
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
// A house rule defined in the operator's canonical rules file cannot be known to
|
|
138
|
+
// this workflow. Rejecting it here is what a hardcoded list did, and it silently
|
|
139
|
+
// disabled every custom rule a deployment configured.
|
|
140
|
+
check('a custom house rule is a hard rule',
|
|
141
|
+
isHardRule({ rule: 'SEC-1', file: 'a.ts', line: 1, title: 't', badCode: '', description: '' }), true)
|
|
133
142
|
|
|
134
|
-
console.log('\nverification scope
|
|
143
|
+
console.log('\nverification scope: depth controls breadth, never the trust bar')
|
|
135
144
|
const crit = { severity: 'critical' }, imp = { severity: 'important' }, obs = { severity: 'observation' }
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
check('
|
|
139
|
-
check('
|
|
140
|
-
|
|
145
|
+
// shouldVerify takes one argument now. Depth used to be able to switch verification
|
|
146
|
+
// off entirely, which meant a scan-depth review shipped unverified Criticals.
|
|
147
|
+
check('shouldVerify takes the finding alone', shouldVerify.length, 1)
|
|
148
|
+
check('critical and important are verified, observation is not',
|
|
149
|
+
[crit, imp, obs].map(f => shouldVerify(f)), [true, true, false])
|
|
150
|
+
check('a hard rule is NOT exempt from verification',
|
|
151
|
+
shouldVerify({ severity: 'critical', rule: 'TS-2', file: 'x.js', badCode: '', description: '', title: '' }), true)
|
|
152
|
+
check('a custom hard rule is NOT exempt either',
|
|
153
|
+
shouldVerify({ severity: 'critical', rule: 'SEC-1', file: 'x.ts', badCode: '', description: '', title: '' }), true)
|
|
141
154
|
|
|
142
155
|
// Per-host model routing is optional: a deployment may pin models per host via
|
|
143
156
|
// a MODEL_TABLE, or leave every agent() call to name its own model. Test it
|