* fix(#3303): correct code_review_depth doc; add agent_skills array form * fix(#3303): backfill changeset pr field --------- Co-authored-by: sim <sim@local>
This commit is contained in:
5
.changeset/sturdy-koalas-zip.md
Normal file
5
.changeset/sturdy-koalas-zip.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
type: Fixed
|
||||||
|
pr: 3449
|
||||||
|
---
|
||||||
|
planning-config.md documented "light" as an allowed workflow.code_review_depth value, but config-set only accepts quick/standard/deep — the reference now matches the validator, pinned by a doc↔capability-registry parity test. The agent_skills row now also documents the array-of-strings form for assigning multiple skill sets to one agent type.
|
||||||
@@ -275,7 +275,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
|||||||
| `workflow.code_review_command` | string\|null | `null` | Any shell command | External code-review command integrated into `/gsd:ship`. The diff is piped to the command via stdin; the command must output JSON with a `verdict` field (`"APPROVED"` or `"REVISE"`). Non-zero exit or `"REVISE"` verdict blocks the ship workflow. When unset, the built-in review flow runs. Example: `my-review-tool --review`. |
|
| `workflow.code_review_command` | string\|null | `null` | Any shell command | External code-review command integrated into `/gsd:ship`. The diff is piped to the command via stdin; the command must output JSON with a `verdict` field (`"APPROVED"` or `"REVISE"`). Non-zero exit or `"REVISE"` verdict blocks the ship workflow. When unset, the built-in review flow runs. Example: `my-review-tool --review`. |
|
||||||
| `workflow.inline_plan_threshold` | number | `2` | `0`–`10` | Plans with ≤N tasks execute inline instead of spawning a subagent |
|
| `workflow.inline_plan_threshold` | number | `2` | `0`–`10` | Plans with ≤N tasks execute inline instead of spawning a subagent |
|
||||||
| `workflow.code_review` | boolean | `true` | `true`, `false` | Enable built-in code review step in the ship workflow |
|
| `workflow.code_review` | boolean | `true` | `true`, `false` | Enable built-in code review step in the ship workflow |
|
||||||
| `workflow.code_review_depth` | string | `"standard"` | `"light"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
|
| `workflow.code_review_depth` | string | `"standard"` | `"quick"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
|
||||||
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
|
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
|
||||||
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd:secure-phase`. When `false`, security checks are skipped entirely |
|
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd:secure-phase`. When `false`, security checks are skipped entirely |
|
||||||
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive. Scales both planner threat-disposition rigor (which threats must be mitigated vs. accepted) and auditor verification depth (grep-level → boundary-placement check → full data-flow trace). See `gsd-core/references/security-asvs-levels.md`. |
|
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive. Scales both planner threat-disposition rigor (which threats must be mitigated vs. accepted) and auditor verification depth (grep-level → boundary-placement check → full data-flow trace). See `gsd-core/references/security-asvs-levels.md`. |
|
||||||
@@ -362,7 +362,7 @@ Set via `manager.*` namespace (e.g., `"manager": { "flags": { "discuss": "--auto
|
|||||||
|-----|------|---------|----------------|-------------|
|
|-----|------|---------|----------------|-------------|
|
||||||
| `parallelization` | boolean\|object | `true` | `true`, `false`, `{ "enabled": true }` | Enable parallel wave execution; object form allows additional sub-keys |
|
| `parallelization` | boolean\|object | `true` | `true`, `false`, `{ "enabled": true }` | Enable parallel wave execution; object form allows additional sub-keys |
|
||||||
| `model_overrides` | object\|null | `null` | `{ "<agent-type>": "<model-id>" }` | Override model selection per agent type |
|
| `model_overrides` | object\|null | `null` | `{ "<agent-type>": "<model-id>" }` | Override model selection per agent type |
|
||||||
| `agent_skills` | object | `{}` | `{ "<agent-type>": "<skill-set>" }` | Assign skill sets to specific agent types |
|
| `agent_skills` | object | `{}` | `{ "<agent-type>": "<skill-set>" }` or `{ "<agent-type>": ["<skill-set>", "<skill-set>", ...] }` | Assign skill sets to specific agent types. Each value is a single skill-set path (string) or an array of skill-set paths — the array form assigns multiple skill sets to one agent type. Paths cannot be comma-joined into one string; each path must be its own array element |
|
||||||
| `sub_repos` | array | `[]` | Array of relative path strings | Child directories with independent `.git` repos (auto-detected) |
|
| `sub_repos` | array | `[]` | Array of relative path strings | Child directories with independent `.git` repos (auto-detected) |
|
||||||
|
|
||||||
### Planning Fields
|
### Planning Fields
|
||||||
|
|||||||
@@ -238,6 +238,82 @@ describe('config-field-docs', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── Capability-enum doc parity (#3303) ─────────────────────────────────────
|
||||||
|
|
||||||
|
describe('capability-enum doc parity (#3303)', () => {
|
||||||
|
const CAPABILITY_PATH = path.join(
|
||||||
|
__dirname, '..', 'capabilities', 'code-review', 'capability.json'
|
||||||
|
);
|
||||||
|
|
||||||
|
let docContent;
|
||||||
|
let capability;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
docContent = fs.readFileSync(REFERENCE_PATH, 'utf-8');
|
||||||
|
capability = JSON.parse(fs.readFileSync(CAPABILITY_PATH, 'utf-8'));
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract a single Complete-Field-Reference table row by key and split it into
|
||||||
|
* trimmed cells: ['', '`key`', type, default, allowedValues, description, ''].
|
||||||
|
* Row-scoping keeps unrelated wording elsewhere in the doc from satisfying
|
||||||
|
* (or breaking) the parity assertions.
|
||||||
|
*/
|
||||||
|
function docRow(key) {
|
||||||
|
const line = docContent
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.find(l => l.startsWith(`| \`${key}\` |`));
|
||||||
|
assert.ok(line, `planning-config.md must have a table row for \`${key}\``);
|
||||||
|
return line.split('|').map(c => c.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
test('workflow.code_review_depth allowed values match the capability registry (#3303)', () => {
|
||||||
|
const spec = capability.config && capability.config['workflow.code_review_depth'];
|
||||||
|
assert.ok(
|
||||||
|
spec && Array.isArray(spec.values),
|
||||||
|
'capabilities/code-review/capability.json must declare workflow.code_review_depth values'
|
||||||
|
);
|
||||||
|
|
||||||
|
const allowedCell = docRow('workflow.code_review_depth')[4];
|
||||||
|
const docValues = [...allowedCell.matchAll(/"([^"]+)"/g)].map(m => m[1]);
|
||||||
|
assert.ok(
|
||||||
|
docValues.length > 0,
|
||||||
|
`workflow.code_review_depth Allowed-Values cell must list quoted values, got: ${allowedCell}`
|
||||||
|
);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
[...docValues].sort(),
|
||||||
|
[...spec.values].sort(),
|
||||||
|
`planning-config.md workflow.code_review_depth allowed values (${docValues.join(', ')}) ` +
|
||||||
|
`must exactly match what config-set accepts per capability.json (${spec.values.join(', ')})`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('workflow.code_review_depth default matches the capability registry (#3303)', () => {
|
||||||
|
const spec = capability.config && capability.config['workflow.code_review_depth'];
|
||||||
|
assert.ok(spec, 'capability.json must declare workflow.code_review_depth');
|
||||||
|
const defaultCell = docRow('workflow.code_review_depth')[3];
|
||||||
|
const [docDefault] = [...defaultCell.matchAll(/"([^"]+)"/g)].map(m => m[1]);
|
||||||
|
assert.strictEqual(
|
||||||
|
docDefault,
|
||||||
|
spec.default,
|
||||||
|
`planning-config.md workflow.code_review_depth default must match capability.json default (${spec.default})`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('agent_skills row documents the array-of-strings form (#3303)', () => {
|
||||||
|
const cells = docRow('agent_skills');
|
||||||
|
const allowedCell = cells[4];
|
||||||
|
assert.ok(
|
||||||
|
/\[\s*"<skill-set>"\s*,/.test(allowedCell),
|
||||||
|
`agent_skills Allowed-Values cell must show the array-of-strings form, got: ${allowedCell}`
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
/array/i.test(cells[5]),
|
||||||
|
'agent_skills description must explain the array form assigns multiple skill sets to one agent type'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ─── CONFIGURATION.md parity (#1216) ────────────────────────────────────────
|
// ─── CONFIGURATION.md parity (#1216) ────────────────────────────────────────
|
||||||
|
|
||||||
describe('CONFIGURATION.md parity (#1216)', () => {
|
describe('CONFIGURATION.md parity (#1216)', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user