* test(#2939): prove shouldFlattenDispatch ignores the depth budget Failing-first regression for #2939. shouldFlattenDispatch checks only background+backgroundDispatch, never nested/subagentToolkit/maxDepth, so a maxDepth:1 descriptor (no room for a bg orchestrator plus a leaf) is told it may background. Row 1 (codex-like, maxDepth:1) asserts true (flatten) and fails today; rows 2/3 guard the unchanged depth-sufficient cases. * fix(#2939): honor the declared depth budget in shouldFlattenDispatch shouldFlattenDispatch checked only background+backgroundDispatch, never nested/subagentToolkit/maxDepth, so a maxDepth:1 descriptor (no room for a backgrounded orchestrator plus a delegated leaf) was told it may background — producing a depth-2 tree (Codex MultiAgent V2) the declared contract cannot support. canBackground now ALSO requires nested:true + subagentToolkit:"full" + a depth budget > 1 (or unbounded -1), reusing the exact predicate shape from bin/install.js _normalizeDispatchCallSpan and matching degradationFor's treatment of maxDepth===1 as flat. Non-finite/missing maxDepth fails closed to flatten. Correct the two existing pins that asserted the buggy output (bare {bg,bgDispatch} now fail-closes on missing depth; the codex-like maxDepth:1 pin flips to flatten) and add a maxDepth:2 negative-space row. * fix(#2939): propagate depth-aware flatten to all pinned descriptors + tests The isolated adversarial review found the depth-aware predicate reclassifies codex/kimi/kimi-code (previously background-eligible under the two-field rule) to flatten — the correct behavior, since each lacks what a backgrounded nesting orchestrator needs: - codex: maxDepth:1 (no room for a depth-2 leaf) - kimi: nested:false (cannot host a nesting orchestrator) - kimi-code: subagentToolkit:'built-in-only' (cannot delegate to full subagents) Only cursor (maxDepth:2) remains background-eligible. Update the three test files that pinned the old contract (host-integration-descriptors EXPECTED_FLATTEN, kimi-upgrades UPGRADE 2, trae-imperative-reference), and align the unbounded convention to maxDepth < 0 (matching degradationFor/negotiateHostCapabilities) with an accurate docstring noting the deliberate nested-check addition over _normalizeDispatchCallSpan. * fix(#2939): update dispatch-should-flatten CLI query pins for codex The depth-aware rule (a0ad0f680) reclassifies codex (maxDepth:1) to flatten, but command-routing-hub.test.cjs exercises the contract through the CLI query route (runGsdTools query dispatch-should-flatten), not a direct shouldFlattenDispatch call — so neither the reviewer's caller-search nor a grep for the symbol found it; only the full gsd-test matrix did. Update the codex query assertions to shouldFlatten=true (maxDepth:1 insufficient), preserving cursor (maxDepth:2 → false) and the backgroundDispatch:true descriptor field. * chore(#2939): add changeset fragment pr:0 placeholder backfilled with the real PR number once the PR exists. * fix(#2939): rephrase changeset for product-name-purity + opencode flatten pin Two failures from the full gsd-test matrix on the prior sha: 1. product-name-purity: changeset fragments must not include parenthetical product descriptions (they render verbatim into CHANGELOG.md). 'Codex (and kimi/kimi-code)' tripped it — rephrase to lead with the behavior, naming runtimes inline without the parenthetical. lint:ci changeset-lint does not catch this; only the test does. 2. opencode-imperative-reference: the #2087-retraction pin flipped only the two background booleans and asserted shouldFlatten:false. Under #2939 that is no longer sufficient (opencode lacks nested + full toolkit + depth budget), so the retracted axes now correctly flatten — update the pin to true with rationale. * chore(#2939): backfill changeset PR number 3063 --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -955,9 +955,12 @@ describe('Phase B: shouldFlattenDispatch — contract pin', () => {
|
||||
'shouldFlattenDispatch must be exported from host-integration module');
|
||||
});
|
||||
|
||||
test('{background:true, backgroundDispatch:true} → false (background OK)', () => {
|
||||
assert.strictEqual(shouldFlattenDispatch({ background: true, backgroundDispatch: true }), false,
|
||||
'canBackground=true when both background===true AND backgroundDispatch===true → flatten=false');
|
||||
test('{background:true, backgroundDispatch:true} → true (no depth budget declared → fail-closed/flatten)', () => {
|
||||
// #2939: can background AT ALL, but declares no nested/toolkit/maxDepth, so the depth
|
||||
// budget is unknown → fail-closed to inline (flatten). A real background-eligible host
|
||||
// also carries nested:true + subagentToolkit:"full" + a sufficient maxDepth.
|
||||
assert.strictEqual(shouldFlattenDispatch({ background: true, backgroundDispatch: true }), true,
|
||||
'canBackground=true but no depth budget declared → fail-closed/flatten=true');
|
||||
});
|
||||
|
||||
test('{background:true, backgroundDispatch:false} → true (must flatten)', () => {
|
||||
@@ -1003,12 +1006,24 @@ describe('Phase B: shouldFlattenDispatch — contract pin', () => {
|
||||
'non-object dispatch (string) must fail-closed to true');
|
||||
});
|
||||
|
||||
// #853 codex-like profile: full dispatch including backgroundDispatch:true → background OK
|
||||
test('#853 codex-like: {namedDispatch:true,nested:true,maxDepth:1,background:true,subagentToolkit:"full",backgroundDispatch:true} → false (background OK)', () => {
|
||||
// #2939: the codex-like profile with maxDepth:1 now FLATTENS. A depth budget of 1 is consumed
|
||||
// by the backgrounded orchestrator itself (depth 1) and leaves no room for the delegated leaf
|
||||
// (depth 2) its own contract requires. This corrects the prior pin, which asserted the buggy
|
||||
// shouldFlatten:false output that permitted a depth-2 tree the descriptor cannot support.
|
||||
test('#2939 codex-like: {namedDispatch:true,nested:true,maxDepth:1,background:true,subagentToolkit:"full",backgroundDispatch:true} → true (flatten — depth budget insufficient)', () => {
|
||||
assert.strictEqual(
|
||||
shouldFlattenDispatch({ namedDispatch: true, nested: true, maxDepth: 1, background: true, subagentToolkit: 'full', backgroundDispatch: true }),
|
||||
true,
|
||||
'maxDepth:1 is insufficient for a backgrounded orchestrator plus a delegated leaf → flatten=true',
|
||||
);
|
||||
});
|
||||
|
||||
// #2939 negative-space: the same codex-like profile with a SUFFICIENT depth budget backgrounds.
|
||||
test('#2939 codex-like maxDepth:2 → false (background OK — depth budget sufficient)', () => {
|
||||
assert.strictEqual(
|
||||
shouldFlattenDispatch({ namedDispatch: true, nested: true, maxDepth: 2, background: true, subagentToolkit: 'full', backgroundDispatch: true }),
|
||||
false,
|
||||
'codex-like dispatch with backgroundDispatch:true must be background-OK (flatten=false)',
|
||||
'maxDepth:2 leaves room for a backgrounded orchestrator plus a leaf → background OK',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user