claude-dev-env 8.88.7 → 8.90.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.
Files changed (91) hide show
  1. package/.agents/skills/pr-visual/README.md +29 -0
  2. package/.agents/skills/pr-visual/SKILL.md +62 -0
  3. package/.agents/skills/pr-visual/assets/icons.symbols +27 -0
  4. package/.agents/skills/pr-visual/assets/viewer.html +147 -0
  5. package/.agents/skills/pr-visual/fixtures/bar.scene.json +193 -0
  6. package/.agents/skills/pr-visual/fixtures/flow.scene.json +201 -0
  7. package/.agents/skills/pr-visual/fixtures/head/metrics.json +16 -0
  8. package/.agents/skills/pr-visual/fixtures/integrated.scene.json +239 -0
  9. package/.agents/skills/pr-visual/fixtures/line.scene.json +193 -0
  10. package/.agents/skills/pr-visual/fixtures/scatter.scene.json +193 -0
  11. package/.agents/skills/pr-visual/fixtures/snapshot.json +21 -0
  12. package/.agents/skills/pr-visual/references/evidence.md +9 -0
  13. package/.agents/skills/pr-visual/references/formats.md +30 -0
  14. package/.agents/skills/pr-visual/references/scene-contract.md +48 -0
  15. package/.agents/skills/pr-visual/references/visual-contract.md +23 -0
  16. package/.agents/skills/pr-visual/scripts/collect.py +111 -0
  17. package/.agents/skills/pr-visual/scripts/metrics.py +99 -0
  18. package/.agents/skills/pr-visual/scripts/render.py +133 -0
  19. package/.agents/skills/pr-visual/scripts/test_collect.py +58 -0
  20. package/.agents/skills/pr-visual/scripts/test_metrics.py +47 -0
  21. package/.agents/skills/pr-visual/scripts/test_render.py +77 -0
  22. package/.agents/skills/pr-visual/scripts/verify.py +218 -0
  23. package/.agents/skills/pr-visual/scripts/visual_config/config/constants.py +104 -0
  24. package/bin/codex-skill-load-block.mjs +0 -25
  25. package/bin/codex-skill-load-block.test.mjs +5 -17
  26. package/bin/codex-trimmed-sol.test.mjs +0 -1
  27. package/bin/cursor-native-hooks.test.mjs +3 -3
  28. package/bin/ever-shipped-skills.mjs +1 -0
  29. package/bin/install-constants.mjs +3 -0
  30. package/bin/install-deepstack-plugin.mjs +42 -25
  31. package/bin/install-deepstack-plugin.test.mjs +37 -11
  32. package/bin/install-pstack-plugin.mjs +58 -11
  33. package/bin/install-pstack-plugin.test.mjs +54 -21
  34. package/bin/install.agents-home.test.mjs +0 -1
  35. package/bin/install.codex-rules.test.mjs +0 -2
  36. package/bin/install.cursor-rules.test.mjs +96 -21
  37. package/bin/install.mjs +48 -44
  38. package/bin/install.pr-visual.test.mjs +40 -0
  39. package/bin/install.prompt-context.test.mjs +3 -4
  40. package/bin/install.prune.test.mjs +0 -1
  41. package/bin/install.question-presentation.test.mjs +0 -4
  42. package/bin/install.settings-defaults.test.mjs +0 -1
  43. package/bin/install.shared-settings.test.mjs +0 -1
  44. package/bin/install.test.mjs +14 -44
  45. package/bin/install.transaction.test.mjs +0 -8
  46. package/bin/install.uninstall-transaction.test.mjs +0 -2
  47. package/bin/install.update-keeps-hooks.test.mjs +0 -1
  48. package/docs/BDD_SCENARIO_QUALITY.md +1 -1
  49. package/docs/BDD_TEST_LAYOUT.md +1 -1
  50. package/docs/CODE_RULES.md +1 -1
  51. package/docs/rule-guides/deepstack-wording.md +3 -5
  52. package/docs/rule-guides/session-title.md +5 -4
  53. package/hooks/advisory/owned_pr_review_loop.py +365 -0
  54. package/hooks/advisory/test_owned_pr_review_loop.py +369 -0
  55. package/hooks/blocking/session_title_turn_gate.py +287 -0
  56. package/hooks/blocking/test_session_title_format_gate.py +5 -0
  57. package/hooks/blocking/test_session_title_turn_gate.py +264 -0
  58. package/hooks/features/bash-dispatchers.md +3 -0
  59. package/hooks/features/conduct-gates.md +3 -0
  60. package/hooks/features/session-context.md +0 -4
  61. package/hooks/hooks.json +15 -5
  62. package/hooks/hooks_constants/mod_handoff_constants.py +0 -2
  63. package/hooks/hooks_constants/owned_pr_review_loop_constants.py +120 -0
  64. package/hooks/hooks_constants/session_title_constants.py +41 -3
  65. package/hooks/lifecycle/nested_project_hooks.py +2 -2
  66. package/hooks/lifecycle/test_nested_project_hooks.py +2 -2
  67. package/hooks/session/compaction_user_messages.py +2 -2
  68. package/package.json +2 -2
  69. package/rules/deepstack-wording.md +3 -3
  70. package/scripts/ci/install-playtest.mjs +58 -314
  71. package/scripts/ci/install-playtest.test.mjs +24 -6
  72. package/scripts/policy_lint/adapter_configuration.py +1 -0
  73. package/scripts/policy_lint/config/constants.py +1 -0
  74. package/scripts/test_deepstack_review_criterion.py +2 -3
  75. package/scripts/test_deepstack_wording_rule.py +6 -4
  76. package/scripts/tests/test_adapter_configuration.py +8 -0
  77. package/.agents/skills/deepen/SKILL.md +0 -26
  78. package/commands/deepen.md +0 -14
  79. package/docs/decisions/deepstack-gate.md +0 -32
  80. package/hooks/hooks_constants/deepen_first_prompt_constants.py +0 -187
  81. package/hooks/session/deepen_default_rewrite.py +0 -128
  82. package/hooks/session/deepen_first_prompt.py +0 -383
  83. package/hooks/session/deepen_role_gate.py +0 -171
  84. package/hooks/session/deepen_turn_marker.py +0 -75
  85. package/hooks/session/fixtures/deepstack_replay.json +0 -15
  86. package/hooks/session/grade_deepstack_replay.py +0 -78
  87. package/hooks/session/test_deepen_default_rewrite.py +0 -90
  88. package/hooks/session/test_deepen_first_prompt.py +0 -452
  89. package/hooks/session/test_deepen_role_gate.py +0 -83
  90. package/hooks/session/test_deepen_turn_marker.py +0 -59
  91. package/hooks/session/test_grade_deepstack_replay.py +0 -47
@@ -57,6 +57,7 @@ import {
57
57
  } from './install.mjs';
58
58
  import { EVER_SHIPPED_SKILL_NAMES } from './ever-shipped-skills.mjs';
59
59
  import {
60
+ DEEPEN_GUIDANCE_BLOCK_END,
60
61
  DEEPEN_GUIDANCE_BLOCK_START,
61
62
  PACKAGE_GUIDANCE_BLOCK_END,
62
63
  PACKAGE_GUIDANCE_BLOCK_START,
@@ -257,9 +258,9 @@ test('CORE_SKILLS ships ELI5 as the leaf presentation skill', () => {
257
258
  assert.equal(INSTALL_GROUPS.core.skills.includes('eli5'), true);
258
259
  });
259
260
 
260
- test('CORE_SKILLS ships deepen so the first-task skill installs with core', () => {
261
- assert.ok(CORE_SKILLS.includes('deepen'), 'deepen must be in CORE_SKILLS');
262
- assert.equal(INSTALL_GROUPS.core.skills.includes('deepen'), true);
261
+ test('CORE_SKILLS leaves out the retired deepen skill', () => {
262
+ assert.equal(CORE_SKILLS.includes('deepen'), false);
263
+ assert.equal(INSTALL_GROUPS.core.skills.includes('deepen'), false);
263
264
  });
264
265
 
265
266
  test('CORE_SKILLS ships efficient-review so a core install includes the skill', () => {
@@ -1243,6 +1244,7 @@ test('retired hook registrations stay managed so reinstall removes them', () =>
1243
1244
  'blocking/artifact_look_gate.py',
1244
1245
  'blocking/session_title_stop_gate.py',
1245
1246
  'session/issue_tracker_session_starter.py',
1247
+ 'session/deepen_first_prompt.py',
1246
1248
  ]);
1247
1249
  const shippedHooks = JSON.parse(
1248
1250
  readFileSync(new URL('../hooks/hooks.json', import.meta.url), 'utf8')
@@ -3048,7 +3050,6 @@ test('a failed update preserves an existing skills lookup pointer', () => {
3048
3050
  CDE_INSTALL_DEEPSTACK: '0',
3049
3051
  CDE_INSTALL_USAGE_WRAPUP: '0',
3050
3052
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3051
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3052
3053
  };
3053
3054
  const argumentsForCoreInstall = [PSTACK_TEST_INSTALLER_PATH, '--only', 'core'];
3054
3055
  const firstRun = spawnSync(process.execPath, argumentsForCoreInstall, {
@@ -3103,7 +3104,6 @@ function runPstackInstaller(homeDirectory, extraArguments, environmentOverrides
3103
3104
  CDE_INSTALL_DEEPSTACK: '0',
3104
3105
  CDE_INSTALL_USAGE_WRAPUP: '0',
3105
3106
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3106
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3107
3107
  ...environmentOverrides,
3108
3108
  },
3109
3109
  });
@@ -3213,10 +3213,7 @@ test('a full install adds DeepStack for Claude, Codex, and Cursor', t => {
3213
3213
  hooks.hooks.sessionStart.filter(entry => entry.command.includes('session-start.sh')).length,
3214
3214
  1,
3215
3215
  );
3216
- assert.equal(
3217
- hooks.hooks.beforeSubmitPrompt.filter(entry => entry.command.includes('deepen_first_prompt.py')).length,
3218
- 1,
3219
- );
3216
+ assert.equal(JSON.stringify(hooks).includes('deepen_first_prompt.py'), false, 'no retired first-task hook');
3220
3217
  assert.equal(JSON.stringify(hooks).includes('"hooks":[{'), false, 'no Claude-style group entries');
3221
3218
  const sheet = readFileSync(join(sandbox.homeDirectory, '.codex', 'deepstack-models.md'), 'utf8');
3222
3219
  assert.match(sheet, /^session hook: on$/m);
@@ -3228,7 +3225,8 @@ test('a repeat install preserves Codex pstack configuration', t => {
3228
3225
  runPstackInstaller(sandbox.homeDirectory, [], sandbox.environment);
3229
3226
  writeFileSync(
3230
3227
  join(codexHome, 'AGENTS.md'),
3231
- `${SKILL_LOAD_BLOCK_START}\n${STALE_SKILL_LOAD_SENTENCE}\n${SKILL_LOAD_BLOCK_END}\nCustom Codex guidance\n`,
3228
+ `${SKILL_LOAD_BLOCK_START}\n${STALE_SKILL_LOAD_SENTENCE}\n${SKILL_LOAD_BLOCK_END}\nCustom Codex guidance\n`
3229
+ + `${DEEPEN_GUIDANCE_BLOCK_START}\nDeepen the first interactive user task.\n${DEEPEN_GUIDANCE_BLOCK_END}\n`,
3232
3230
  );
3233
3231
  writeFileSync(join(codexHome, 'pstack-models.md'), 'session hook: off\n');
3234
3232
 
@@ -3238,7 +3236,7 @@ test('a repeat install preserves Codex pstack configuration', t => {
3238
3236
  assert.ok(codexGuidance.startsWith('Custom Codex guidance\n'));
3239
3237
  assertOmitsSkillLoadSentence(codexGuidance);
3240
3238
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3241
- assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3239
+ assert.equal(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START), false);
3242
3240
  assert.equal(readFileSync(join(codexHome, 'pstack-models.md'), 'utf8'), 'session hook: off\n');
3243
3241
  });
3244
3242
 
@@ -3322,7 +3320,7 @@ test('a fresh full install writes the package guidance into Codex AGENTS.md', t
3322
3320
  assertHoldsPackageGuidance(codexGuidance);
3323
3321
  assertOmitsSkillLoadSentence(codexGuidance);
3324
3322
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3325
- assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3323
+ assert.equal(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START), false);
3326
3324
  });
3327
3325
 
3328
3326
  test('--no-pstack writes package and question guidance without the skill-load block', t => {
@@ -3405,7 +3403,7 @@ test('a pstack install after a --no-pstack install seeds the Codex model sheet',
3405
3403
  assertOmitsSkillLoadSentence(codexGuidance);
3406
3404
  assertHoldsPackageGuidance(codexGuidance);
3407
3405
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3408
- assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3406
+ assert.equal(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START), false);
3409
3407
  });
3410
3408
 
3411
3409
  const USAGE_WRAPUP_CLAUDE_COMMANDS = Object.freeze([
@@ -3483,18 +3481,16 @@ test('the help output names the usage-wrapup opt-out beside the pstack one', ()
3483
3481
 
3484
3482
  assert.equal(helpRun.status, 0, helpRun.stderr);
3485
3483
  assert.match(helpRun.stdout, /--no-pstack .*\n.*--no-deepstack .*CDE_INSTALL_DEEPSTACK=0.*\n.*--no-usage-wrapup .*CDE_INSTALL_USAGE_WRAPUP=0/);
3486
- assert.match(helpRun.stdout, /--no-deepen-first-prompt .*CDE_INSTALL_DEEPEN_FIRST_PROMPT=0/);
3484
+ assert.doesNotMatch(helpRun.stdout, /--no-deepen-first-prompt/);
3487
3485
  });
3488
3486
 
3489
3487
  const REPOSITORY_PLUGIN_CLAUDE_COMMANDS = Object.freeze([
3490
3488
  'claude plugin uninstall usage-wrapup@claude-dev-env',
3491
3489
  'claude plugin uninstall subagent-models@claude-dev-env',
3492
- 'claude plugin uninstall deepen-first-prompt@claude-dev-env',
3493
3490
  'claude plugin marketplace remove claude-dev-env',
3494
- 'claude plugin marketplace add jl-cmd-projects/claude-dev-env --sparse .claude-plugin packages/usage-wrapup packages/subagent-models packages/deepen-first-prompt',
3491
+ 'claude plugin marketplace add jl-cmd-projects/claude-dev-env --sparse .claude-plugin packages/usage-wrapup packages/subagent-models',
3495
3492
  'claude plugin install usage-wrapup@claude-dev-env',
3496
3493
  'claude plugin install subagent-models@claude-dev-env',
3497
- 'claude plugin install deepen-first-prompt@claude-dev-env',
3498
3494
  ]);
3499
3495
 
3500
3496
  test('should install subagent-models beside usage-wrapup with one marketplace add on a full install', t => {
@@ -3504,13 +3500,12 @@ test('should install subagent-models beside usage-wrapup with one marketplace ad
3504
3500
  ...sandbox.environment,
3505
3501
  CDE_INSTALL_USAGE_WRAPUP: '1',
3506
3502
  CDE_INSTALL_SUBAGENT_MODELS: '1',
3507
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1',
3508
3503
  });
3509
3504
 
3510
3505
  assert.deepEqual(usageWrapupCommands(sandbox.recordedCommands()), REPOSITORY_PLUGIN_CLAUDE_COMMANDS);
3511
3506
  assert.match(installerOutput, /Usage-wrapup \(claude\): installed/);
3512
3507
  assert.match(installerOutput, /Subagent-models \(claude\): installed/);
3513
- assert.match(installerOutput, /Deepen-first-prompt \(claude\): installed/);
3508
+ assert.doesNotMatch(installerOutput, /Deepen-first-prompt \(/);
3514
3509
  });
3515
3510
 
3516
3511
  for (const [caseName, extraArguments, environmentOverrides] of [
@@ -3534,27 +3529,6 @@ for (const [caseName, extraArguments, environmentOverrides] of [
3534
3529
  });
3535
3530
  }
3536
3531
 
3537
- for (const [caseName, extraArguments, environmentOverrides] of [
3538
- ['--no-deepen-first-prompt', ['--no-deepen-first-prompt'], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1' }],
3539
- ['CDE_INSTALL_DEEPEN_FIRST_PROMPT=0', [], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0' }],
3540
- ['an --only run', ['--only', 'core'], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1' }],
3541
- ]) {
3542
- test(`should skip deepen-first-prompt on ${caseName}`, t => {
3543
- const sandbox = pstackPluginSandbox(t);
3544
-
3545
- const installerOutput = runPstackInstaller(sandbox.homeDirectory, extraArguments, {
3546
- ...sandbox.environment,
3547
- ...environmentOverrides,
3548
- });
3549
-
3550
- assert.equal(
3551
- sandbox.recordedCommands().some(eachCommand => eachCommand.includes('deepen-first-prompt')),
3552
- false,
3553
- );
3554
- assert.doesNotMatch(installerOutput, /Deepen-first-prompt \(/);
3555
- });
3556
- }
3557
-
3558
3532
  test('should name the subagent-models opt-out in the help output', () => {
3559
3533
  const helpRun = spawnSync(process.execPath, [PSTACK_TEST_INSTALLER_PATH, '--help'], {
3560
3534
  encoding: 'utf8',
@@ -3649,7 +3623,6 @@ function installWithGlobalPrefix(context, globalPrefix) {
3649
3623
  CDE_INSTALL_DEEPSTACK: '0',
3650
3624
  CDE_INSTALL_USAGE_WRAPUP: '0',
3651
3625
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3652
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3653
3626
  HOME: homeDirectory,
3654
3627
  USERPROFILE: homeDirectory,
3655
3628
  APPDATA: join(homeDirectory, 'AppData', 'Roaming'),
@@ -3706,7 +3679,6 @@ test('install adds the open-tasks Stop gate to every profile with its own settin
3706
3679
  CDE_INSTALL_DEEPSTACK: '0',
3707
3680
  CDE_INSTALL_USAGE_WRAPUP: '0',
3708
3681
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3709
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3710
3682
  HOME: homeDirectory,
3711
3683
  USERPROFILE: homeDirectory,
3712
3684
  CODEX_HOME: join(homeDirectory, '.codex'),
@@ -3749,7 +3721,6 @@ test('a profile settings.json that is not valid JSON is left alone and named und
3749
3721
  CDE_INSTALL_DEEPSTACK: '0',
3750
3722
  CDE_INSTALL_USAGE_WRAPUP: '0',
3751
3723
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3752
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3753
3724
  HOME: homeDirectory,
3754
3725
  USERPROFILE: homeDirectory,
3755
3726
  CODEX_HOME: join(homeDirectory, '.codex'),
@@ -3795,7 +3766,6 @@ test('uninstall stops before changing anything while a profile settings.json tha
3795
3766
  CDE_INSTALL_DEEPSTACK: '0',
3796
3767
  CDE_INSTALL_USAGE_WRAPUP: '0',
3797
3768
  CDE_INSTALL_SUBAGENT_MODELS: '0',
3798
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
3799
3769
  HOME: homeDirectory,
3800
3770
  USERPROFILE: homeDirectory,
3801
3771
  CODEX_HOME: join(homeDirectory, '.codex'),
@@ -91,7 +91,6 @@ test('capture and restore recover settings, manifest, files, and hooksPath', ()
91
91
  CDE_INSTALL_DEEPSTACK: '0',
92
92
  CDE_INSTALL_USAGE_WRAPUP: '0',
93
93
  CDE_INSTALL_SUBAGENT_MODELS: '0',
94
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
95
94
  HOME: box.root,
96
95
  USERPROFILE: box.root,
97
96
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -158,7 +157,6 @@ test('capture and restore recover an additional host settings file', () => {
158
157
  CDE_INSTALL_DEEPSTACK: '0',
159
158
  CDE_INSTALL_USAGE_WRAPUP: '0',
160
159
  CDE_INSTALL_SUBAGENT_MODELS: '0',
161
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
162
160
  HOME: box.root,
163
161
  USERPROFILE: box.root,
164
162
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -198,7 +196,6 @@ test('runWithInstallTransaction restores prior state on injected fault', () => {
198
196
  CDE_INSTALL_DEEPSTACK: '0',
199
197
  CDE_INSTALL_USAGE_WRAPUP: '0',
200
198
  CDE_INSTALL_SUBAGENT_MODELS: '0',
201
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
202
199
  HOME: box.root,
203
200
  USERPROFILE: box.root,
204
201
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -257,7 +254,6 @@ test('runWithInstallTransaction commits and discards journal on success', () =>
257
254
  CDE_INSTALL_DEEPSTACK: '0',
258
255
  CDE_INSTALL_USAGE_WRAPUP: '0',
259
256
  CDE_INSTALL_SUBAGENT_MODELS: '0',
260
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
261
257
  HOME: box.root,
262
258
  USERPROFILE: box.root,
263
259
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -305,7 +301,6 @@ function runInstaller(homeDirectory, extraArguments, options = {}) {
305
301
  CDE_INSTALL_DEEPSTACK: '0',
306
302
  CDE_INSTALL_USAGE_WRAPUP: '0',
307
303
  CDE_INSTALL_SUBAGENT_MODELS: '0',
308
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
309
304
  HOME: homeDirectory,
310
305
  USERPROFILE: homeDirectory,
311
306
  GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
@@ -343,7 +338,6 @@ test('a later install fault removes newly seeded Codex pstack files', () => {
343
338
  CDE_INSTALL_DEEPSTACK: '0',
344
339
  CDE_INSTALL_USAGE_WRAPUP: '0',
345
340
  CDE_INSTALL_SUBAGENT_MODELS: '0',
346
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
347
341
  CDE_CODEX_EXECUTABLE: codexCommandPath,
348
342
  },
349
343
  });
@@ -491,7 +485,6 @@ test('installer fault after_git_config restores prior core.hooksPath', () => {
491
485
  CDE_INSTALL_DEEPSTACK: '0',
492
486
  CDE_INSTALL_USAGE_WRAPUP: '0',
493
487
  CDE_INSTALL_SUBAGENT_MODELS: '0',
494
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
495
488
  HOME: homeDirectory,
496
489
  USERPROFILE: homeDirectory,
497
490
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -513,7 +506,6 @@ test('installer fault after_git_config restores prior core.hooksPath', () => {
513
506
  CDE_INSTALL_DEEPSTACK: '0',
514
507
  CDE_INSTALL_USAGE_WRAPUP: '0',
515
508
  CDE_INSTALL_SUBAGENT_MODELS: '0',
516
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
517
509
  HOME: homeDirectory,
518
510
  USERPROFILE: homeDirectory,
519
511
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -77,7 +77,6 @@ function runInstaller(homeDirectory, extraArguments, options = {}) {
77
77
  CDE_INSTALL_DEEPSTACK: '0',
78
78
  CDE_INSTALL_USAGE_WRAPUP: '0',
79
79
  CDE_INSTALL_SUBAGENT_MODELS: '0',
80
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
81
80
  HOME: homeDirectory,
82
81
  USERPROFILE: homeDirectory,
83
82
  GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
@@ -316,7 +315,6 @@ test('uninstall fault after_git_config restores prior core.hooksPath', () => {
316
315
  CDE_INSTALL_DEEPSTACK: '0',
317
316
  CDE_INSTALL_USAGE_WRAPUP: '0',
318
317
  CDE_INSTALL_SUBAGENT_MODELS: '0',
319
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
320
318
  HOME: homeDirectory,
321
319
  USERPROFILE: homeDirectory,
322
320
  GIT_CONFIG_GLOBAL: gitConfigPath,
@@ -28,7 +28,6 @@ function installerEnvironment(homeDirectory) {
28
28
  CDE_INSTALL_DEEPSTACK: '0',
29
29
  CDE_INSTALL_USAGE_WRAPUP: '0',
30
30
  CDE_INSTALL_SUBAGENT_MODELS: '0',
31
- CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
32
31
  HOME: homeDirectory,
33
32
  USERPROFILE: homeDirectory,
34
33
  GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
@@ -40,7 +40,7 @@ Then I should be presented with the following hotels:
40
40
 
41
41
  ## Meaningful Actors
42
42
 
43
- Personas ground scenarios in realistic goals and context. Use light soap-opera personas when you need depth before full UX research: introduce names and roles as needed and deepen them across scenarios.
43
+ Personas ground scenarios in realistic goals and context. Use light soap-opera personas when you need depth before full UX research: introduce names and roles as needed and develop them across scenarios.
44
44
 
45
45
  > Smart & Molak §7.6.5 describe personas as rich, realistic descriptions: each persona captures goals, abilities, and background information that ground the test scenario in a user context.
46
46
 
@@ -18,7 +18,7 @@ Dan North (2006): naming tests as sentences keeps focus on the **next behaviour*
18
18
 
19
19
  ## Soap-opera personas
20
20
 
21
- When you lack full personas, introduce **short-lived characters** with a name and role and deepen them as scenarios grow—like a serial drama adding cast over episodes (Smart & Molak §7.6.5). Embed **\[Name], the \[role]** in scenario titles or setup where the actor changes behavior.
21
+ When you lack full personas, introduce **short-lived characters** with a name and role and develop them as scenarios grow—like a serial drama adding cast over episodes (Smart & Molak §7.6.5). Embed **\[Name], the \[role]** in scenario titles or setup where the actor changes behavior.
22
22
 
23
23
  ## Example (JavaScript-style)
24
24
 
@@ -132,4 +132,4 @@ Open [details](code-rules/enforcement-surfaces.md) when adding a check.
132
132
 
133
133
  ## 11.7 A NEW INSTRUCTION NAMES THE TRIGGER THAT COVERS IT
134
134
 
135
- A new rule, hook, or skill names the trigger that covers it and records that trigger in `rules-archived/ARCHIVE-MANIFEST.md`. The first-task gate is `hooks/session/deepen_first_prompt.py`. DeepStack cites that gate. This criterion cites the gate. It does not restate the gate.
135
+ A new rule, hook, or skill names the trigger that covers it and records that trigger in `rules-archived/ARCHIVE-MANIFEST.md`.
@@ -4,9 +4,9 @@ Back to the [rules index](../../rules/index.md).
4
4
 
5
5
  ## In brief
6
6
 
7
- A deepened task uses the three DeepStack labels and puts `CDE_DEEPEN:v1` on line 1. The gate in `hooks/session/deepen_first_prompt.py` is the check. This guide cites that gate.
7
+ A DeepStack task uses the three DeepStack labels. No hook checks them.
8
8
 
9
- **When this applies:** Writing a deepened task, a worker prompt, or a sentence that names the three DeepStack lines.
9
+ **When this applies:** Writing a worker prompt or a sentence that names the three DeepStack lines.
10
10
 
11
11
  ## Labels
12
12
 
@@ -18,6 +18,4 @@ Say "the user" in public text.
18
18
 
19
19
  ## Where it is enforced
20
20
 
21
- | Surface | What runs |
22
- |---|---|
23
- | A first-task rewrite | `hooks/session/deepen_first_prompt.py` |
21
+ Nowhere. The agent applies it.
@@ -4,9 +4,9 @@ Back to the [rules index](../../rules/index.md).
4
4
 
5
5
  ## In brief
6
6
 
7
- Before each turn ends, set the title to `<emoji> <name>`. Use the red flag when the user must act, the check mark when the work is done, and the hourglass while work, CI, or a merge queue runs. The name has 25 characters or fewer, in sentence case, with concrete nouns and no IDs, dates, or branch names.
7
+ Before each turn ends, set the title to `<emoji> <name>`. Use the red flag when the user must act, the construction sign when an outside dependency blocks the work, the check mark when the work is done, and the hourglass while work, CI, or a merge queue runs. The name has 25 characters or fewer, in sentence case, with concrete nouns and no IDs, dates, or branch names.
8
8
 
9
- **Enforcement:** `hooks/blocking/session_title_format_gate.py` denies a malformed title.
9
+ **Enforcement:** `hooks/blocking/session_title_format_gate.py` denies a malformed title. `hooks/blocking/session_title_turn_gate.py` holds a turn that set no title.
10
10
 
11
11
  **When this applies:** The session has a tool whose name ends in `__set_session_title`, such as `mcp__claude-code-remote__set_session_title` in a cloud session or `mcp__ccd_session_mgmt__set_session_title` in the desktop app.
12
12
 
@@ -14,13 +14,14 @@ Before each turn ends, set the title to `<emoji> <name>`. Use the red flag when
14
14
 
15
15
  Before each turn ends, set the title to `<emoji> <name>`. Get the session id from `get_session` with no `session_id` when the tool asks for one.
16
16
 
17
- Set the title before the final reply, and set it in silence. The reply to the user carries no mention of the title, its emoji, or the reminder that asked for it.
17
+ Set the title before the final reply, and set it in silence. The reply to the user carries no mention of the title, its emoji, or the reminder that asked for it. When the Stop gate holds the turn after the answer went out, call the title tool and close with one short sentence. Leave the answer as it stands.
18
18
 
19
19
  ## Status emoji
20
20
 
21
21
  | Emoji | Use it when |
22
22
  |---|---|
23
23
  | Red flag | The user must act: a question, an approval, or a step only the user can do. |
24
+ | Construction sign | An outside dependency blocks the work and the user cannot clear it right now, such as a refused push or an unreachable host. |
24
25
  | Check mark | The work is done: merged, or nothing left. |
25
26
  | Hourglass | Work, CI, or a merge queue still runs and nothing waits on the user. |
26
27
 
@@ -30,4 +31,4 @@ The name has 25 characters or fewer and names the main change or outcome in conc
30
31
 
31
32
  ## Enforcement
32
33
 
33
- `hooks/blocking/session_title_format_gate.py` denies a malformed title.
34
+ `hooks/blocking/session_title_format_gate.py` denies a malformed title. `hooks/blocking/session_title_turn_gate.py` is a Stop hook. It holds the end of a turn until a title call in that turn comes back without an error. It applies when the transcript shows the title tool. A held turn whose title call failed may end, so a failing title tool cannot hold it forever.