Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

index.html 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=en>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Power dynamics — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <!-- Canonical URL for SEO purposes -->
  28. <link rel="canonical" href="https://larlet.fr/david/stream/2018/05/02/">
  29. <style>
  30. /* http://meyerweb.com/eric/tools/css/reset/ */
  31. html, body, div, span,
  32. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  33. a, abbr, address, big, cite, code,
  34. del, dfn, em, img, ins,
  35. small, strike, strong, tt, var,
  36. dl, dt, dd, ol, ul, li,
  37. fieldset, form, label, legend,
  38. table, caption, tbody, tfoot, thead, tr, th, td,
  39. article, aside, canvas, details, embed,
  40. figure, figcaption, footer, header, hgroup,
  41. menu, nav, output, ruby, section, summary,
  42. time, mark, audio, video {
  43. margin: 0;
  44. padding: 0;
  45. border: 0;
  46. font-size: 100%;
  47. font: inherit;
  48. vertical-align: baseline;
  49. }
  50. /* HTML5 display-role reset for older browsers */
  51. article, aside, details, figcaption, figure,
  52. footer, header, hgroup, menu, nav, section { display: block; }
  53. body { line-height: 1; }
  54. blockquote, q { quotes: none; }
  55. blockquote:before, blockquote:after,
  56. q:before, q:after {
  57. content: '';
  58. content: none;
  59. }
  60. table {
  61. border-collapse: collapse;
  62. border-spacing: 0;
  63. }
  64. /* http://practicaltypography.com/equity.html */
  65. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  66. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  67. @font-face {
  68. font-family: 'EquityTextB';
  69. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  70. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  71. font-weight: 300;
  72. font-style: normal;
  73. font-display: swap;
  74. }
  75. @font-face {
  76. font-family: 'EquityTextB';
  77. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  78. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  79. font-weight: 300;
  80. font-style: italic;
  81. font-display: swap;
  82. }
  83. @font-face {
  84. font-family: 'EquityTextB';
  85. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  86. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  87. font-weight: 700;
  88. font-style: normal;
  89. font-display: swap;
  90. }
  91. @font-face {
  92. font-family: 'TriplicateT4c';
  93. src: url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff2') format('woff2'),
  94. url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff') format('woff');
  95. font-weight: 300;
  96. font-style: normal;
  97. font-display: swap;
  98. }
  99. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  100. body {
  101. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  102. font-family: "EquityTextB", Palatino, serif;
  103. background-color: #f0f0ea;
  104. color: #07486c;
  105. font-kerning: normal;
  106. -moz-osx-font-smoothing: grayscale;
  107. -webkit-font-smoothing: subpixel-antialiased;
  108. text-rendering: optimizeLegibility;
  109. font-variant-ligatures: common-ligatures contextual;
  110. font-feature-settings: "kern", "liga", "clig", "calt";
  111. }
  112. pre, code, kbd, samp, var, tt {
  113. font-family: 'TriplicateT4c', monospace;
  114. }
  115. em {
  116. font-style: italic;
  117. color: #323a45;
  118. }
  119. strong {
  120. font-weight: bold;
  121. color: black;
  122. }
  123. nav {
  124. background-color: #323a45;
  125. color: #f0f0ea;
  126. display: flex;
  127. justify-content: space-around;
  128. padding: 1rem .5rem;
  129. }
  130. nav:first-child {
  131. border-top: 1vh solid #2d7474;
  132. }
  133. nav:last-child {
  134. border-bottom: 1vh solid #2d7474;
  135. }
  136. nav a {
  137. color: #f0f0ea;
  138. }
  139. nav abbr {
  140. border-bottom: 1px dotted white;
  141. }
  142. h1 {
  143. border-bottom: .2vh solid #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 2rem 0 1rem;
  148. width: 100%;
  149. }
  150. h2 {
  151. margin: 4rem 0 1rem;
  152. border-top: .2vh solid #2d7474;
  153. }
  154. h3 {
  155. text-align: center;
  156. margin: 3rem 0 .75em;
  157. }
  158. hr {
  159. height: .4rem;
  160. width: .4rem;
  161. border-radius: .4rem;
  162. background: #07486c;
  163. margin: 2.5rem auto;
  164. }
  165. time {
  166. display: bloc;
  167. background-color: #2d7474;
  168. color: #e3e1e1;
  169. padding: .29rem 1rem;
  170. float: right;
  171. }
  172. ul, ol {
  173. margin: 2rem;
  174. }
  175. ul {
  176. list-style-type: square;
  177. }
  178. a {
  179. text-decoration-skip-ink: auto;
  180. }
  181. article {
  182. max-width: 50rem;
  183. display: flex;
  184. flex-direction: column;
  185. margin: 3rem auto 1rem auto;
  186. }
  187. article p:last-child {
  188. margin-bottom: 1rem;
  189. }
  190. p {
  191. padding: 0 .5rem;
  192. }
  193. p + p {
  194. margin-top: 2rem;
  195. }
  196. blockquote {
  197. background-color: #e3e1e1;
  198. border-left: .5vw solid #2d7474;
  199. display: flex;
  200. flex-direction: column;
  201. align-items: center;
  202. padding: 1rem;
  203. margin: 1.5rem;
  204. }
  205. blockquote cite {
  206. font-style: italic;
  207. }
  208. figure {
  209. border-top: .2vh solid #2d7474;
  210. background-color: #e3e1e1;
  211. text-align: center;
  212. padding: 1.5rem 0;
  213. margin: 1rem 0 0;
  214. font-size: 1.5rem;
  215. width: 100%;
  216. }
  217. figure img {
  218. width: 250px;
  219. height: 250px;
  220. border: .5vw solid #323a45;
  221. padding: 1px;
  222. }
  223. figcaption {
  224. padding: 1rem;
  225. line-height: 1.4;
  226. }
  227. aside {
  228. display: flex;
  229. flex-direction: column;
  230. background-color: #e3e1e1;
  231. padding: 1rem 0;
  232. border-bottom: .2vh solid #07486c;
  233. }
  234. aside p {
  235. max-width: 50rem;
  236. margin: 0 auto;
  237. }
  238. /* https://fvsch.com/code/css-locks/ */
  239. p, li, pre, code, kbd, samp, var, tt, time {
  240. font-size: .95rem;
  241. line-height: calc( 1.5em + 0.2 * 1rem );
  242. }
  243. h1 {
  244. font-size: 1.7rem;
  245. line-height: calc( 1.2em + 0.2 * 1rem );
  246. }
  247. h2 {
  248. font-size: 1.6rem;
  249. line-height: calc( 1.3em + 0.2 * 1rem );
  250. }
  251. h3 {
  252. font-size: 1.35rem;
  253. line-height: calc( 1.4em + 0.2 * 1rem );
  254. }
  255. @media (min-width: 20em) {
  256. /* The (100vw - 20rem) / (50 - 20) part
  257. resolves to 0-1rem, depending on the
  258. viewport width (between 20em and 50em). */
  259. p, li, pre, code, kbd, samp, var, tt, time {
  260. font-size: calc( .95rem + .6 * (100vw - 20rem) / (50 - 20) );
  261. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  262. }
  263. h1 {
  264. font-size: calc( 1.7rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  265. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  266. }
  267. h2 {
  268. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  269. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  270. }
  271. h3 {
  272. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  273. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  274. }
  275. }
  276. @media (min-width: 50em) {
  277. /* The right part of the addition *must* be a
  278. rem value. In this example we *could* change
  279. the whole declaration to font-size:2.5rem,
  280. but if our baseline value was not expressed
  281. in rem we would have to use calc. */
  282. p, li, pre, code, kbd, samp, var, tt, time {
  283. font-size: calc( .95rem + .6 * 1rem );
  284. line-height: 1.5em;
  285. }
  286. h1 {
  287. font-size: calc( 1.7rem + 1.5 * 1rem );
  288. line-height: 1.2em;
  289. }
  290. h2 {
  291. font-size: calc( 1.5rem + 1.5 * 1rem );
  292. line-height: 1.3em;
  293. }
  294. h3 {
  295. font-size: calc( 1.35rem + 1.5 * 1rem );
  296. line-height: 1.4em;
  297. }
  298. figure img {
  299. width: 500px;
  300. height: 500px;
  301. }
  302. blockquote {
  303. margin-left: -1.5rem;
  304. }
  305. }
  306. figure.unsquared {
  307. margin-bottom: 1.5rem;
  308. }
  309. figure.unsquared img {
  310. height: inherit;
  311. }
  312. /* https://github.com/richleland/pygments-css */
  313. .codehilite{
  314. background-color: #fdf6e3;
  315. margin: 1rem auto;
  316. padding: 1rem;
  317. overflow-x:auto;
  318. box-shadow:inset 0 0 2px rgba(0,0,0,0.2)
  319. }
  320. .codehilite .t{color:#586e75}
  321. .codehilite .w{color:#073642}
  322. .codehilite .err{color:#cb4b16}
  323. .codehilite .k{color:#859900}
  324. .codehilite .kc{color:#2aa198}
  325. .codehilite .kd{color:#268bd2}
  326. .codehilite .kn{color:#b58900}
  327. .codehilite .kp{color:#859900}
  328. .codehilite .kr{color:#073642}
  329. .codehilite .kt{color:#b58900}
  330. .codehilite .n{color:#586e75}
  331. .codehilite .na{color:#2aa198}
  332. .codehilite .nb{color:#268bd2}
  333. .codehilite .nc{color:#268bd2}
  334. .codehilite .ne{color:#cb4b16}
  335. .codehilite .no{color:#2aa198}
  336. .codehilite .nd{color:#2aa198}
  337. .codehilite .ni{color:#2aa198;font-weight:bold}
  338. .codehilite .nf{color:#268bd2}
  339. .codehilite .nn{color:#586e75}
  340. .codehilite .nt{color:#2aa198;font-weight:bold}
  341. .codehilite .nv{color:#cb4b16}
  342. .codehilite .b{color:#859900}
  343. .codehilite .bp{color:#586e75}
  344. .codehilite .v{color:#586e75}
  345. .codehilite .vc{color:#586e75}
  346. .codehilite .vg{color:#268bd2}
  347. .codehilite .vi{color:#268bd2}
  348. .codehilite .m{color:#268bd2}
  349. .codehilite .mf{color:#268bd2}
  350. .codehilite .mh{color:#268bd2}
  351. .codehilite .mi{color:#268bd2}
  352. .codehilite .mo{color:#268bd2}
  353. .codehilite .s{color:#2aa198}
  354. .codehilite .sb{color:#2aa198}
  355. .codehilite .sc{color:#2aa198}
  356. .codehilite .sd{color:#2aa198}
  357. .codehilite .s2{color:#2aa198}
  358. .codehilite .se{color:#cb4b16}
  359. .codehilite .sh{color:#2aa198}
  360. .codehilite .si{color:#cb4b16}
  361. .codehilite .sx{color:#2aa198}
  362. .codehilite .sr{color:#cb4b16}
  363. .codehilite .s1{color:#2aa198}
  364. .codehilite .ss{color:#cb4b16}
  365. .codehilite .il{color:#268bd2}
  366. .codehilite .o{color:#586e75}
  367. .codehilite .ow{color:#859900}
  368. .codehilite .p{color:#586e75}
  369. .codehilite .c{color:#93a1a1;font-style:italic}
  370. .codehilite .cm{color:#93a1a1}
  371. .codehilite .cp{color:#93a1a1}
  372. .codehilite .c1{color:#93a1a1}
  373. .codehilite .cs{color:#93a1a1}
  374. .codehilite .hll{background-color:#dc322f}
  375. .codehilite .g{color:#586e75}
  376. .codehilite .gd{color:#586e75}
  377. .codehilite .ge{font-style:italic}
  378. .codehilite .gr{color:#586e75}
  379. .codehilite .gh{color:#586e75;font-weight:bold}
  380. .codehilite .gi{color:#586e75}
  381. .codehilite .go{color:#586e75}
  382. .codehilite .gp{color:#586e75}
  383. .codehilite .gs{font-weight:bold}
  384. .codehilite .gu{color:#586e75;font-weight:bold}
  385. .codehilite .gt{color:#586e75}
  386. @media print {
  387. body { font-size: 100%; }
  388. a:after { content: " (" attr(href) ")"; }
  389. a, a:link, a:visited, a:after {
  390. text-decoration: underline;
  391. text-shadow: none !important;
  392. background-image: none !important;
  393. background: white;
  394. color: black;
  395. }
  396. abbr[title] { border-bottom: 0; }
  397. abbr[title]:after { content: " (" attr(title) ")"; }
  398. img { page-break-inside: avoid; }
  399. @page { margin: 2cm .5cm; }
  400. h1, h2, h3 { page-break-after: avoid; }
  401. p3 { orphans: 3; widows: 3; }
  402. img {
  403. max-width: 250px !important;
  404. max-height: 250px !important;
  405. }
  406. nav, aside { display: none; }
  407. }
  408. /* Dark theme */
  409. [lang=en] body {
  410. background: #323a45;
  411. }
  412. [lang=en] article,
  413. [lang=en] article em,
  414. [lang=en] article strong {
  415. color: #f0f0ea;
  416. }
  417. [lang=en] article a {
  418. color: #ffbd2b;
  419. }
  420. [lang=en] article a:visited {
  421. color: #ff6b03;
  422. }
  423. [lang=en] blockquote,
  424. [lang=en] figure {
  425. background: #111930;
  426. color: #ccc;
  427. }
  428. </style>
  429. <nav>
  430. <p>
  431. <a href="/david/" title="Profil public">David&nbsp;Larlet</a> partage ses <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et sa <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a>.
  432. </p>
  433. </nav>
  434. <h1>Power dynamics</h1>
  435. <time>2018-05-02</time>
  436. <article>
  437. <blockquote>
  438. <p>More on why agile/XP so often fails heterogenous teams:</p>
  439. <p>When I first did real (small-a) agile, at @pivotallabs circa 2009, it was clear to me almost immediately that this was the most powerful way to build software that I’d ever participated in.</p>
  440. <p>Pivotal wasn’t a brand so much at that point, and agile hadn’t “won.” I frequently had to explain, discuss, and (ultimately) defend the practices to many of the client developers on my early projects.</p>
  441. <p>By the time I left Pivotal circa 2012, agile had crossed the chasm. Client developers no longer pushed back against the practices - and hadn’t for years, actually.</p>
  442. <p>What practices are we talking about? 100% pair programming. 100% TDD. One week iterations. Daily pair rotation. Standups every day. Planning meetings and retrospectives once a week. And a fixed 9-6 weekday-only schedule to avoid burnout.</p>
  443. <p>Pivotal took a page directly from the XP (eXtreme Programming) workbook. Their CEO, Rob Mee, had worked with some of the signatories on early agile projects, and had been putting it all into practice continuously since then.</p>
  444. <p>I <em>loved</em> working like this. Agile is basically a set of attention hacks for me. For example - when I’m pairing I’m not on Twitter or email - all I’m thinking about is the problem at hand. Devs at Pivotal paired 8 hours every weekday, modulo standups, planning meetings, &amp; retros.</p>
  445. <p>I’d never worked in a way that seemed so likely to produce the <em>right</em> product. That’s the motivator for me - building things that are useful and get used. I’m not motivated by the act of writing code (tedious, error prone) nor by new technology (unless the payoff is clear).</p>
  446. <p>The agile/XP/Pivotal way of working is not without its issues.</p>
  447. <p>But the positives were so strong, relative to my previous experience, that it took me 5 years doing full-on agile to even start to see &amp; articulate &amp; connect the problems.</p>
  448. <p>So let’s start with the obvious issues: </p>
  449. <ul>
  450. <li>Very few people can pair that much. My job was essentially talking for 8 hours a day. </li>
  451. <li>Many people can’t do a 9-6 fixed schedule. Parents, in particular, because no daycare place stays open past 6. This is ultimately why I left Pivotal.</li>
  452. <li>Many people have motivators that don’t mesh well with this system, including pushing frontiers via more research-y code, being in solo ‘flow,’ &amp; using new technology. </li>
  453. <li>Full-time pairing is hard across time zones. Having everyone in the same time zone is often unrealistic.</li>
  454. </ul>
  455. <p>That’s the obvious stuff. Most of it can be solved by employing small-a agile, rather than a program like scrum or XP, so that the process adapts to the needs of the team.</p>
  456. <p>The way I usually approach this is to have folks articulate what they’re trying to get out of a practice that’s not working for them. Then we brainstorm other practices that might have the same effect AND work better for that group.</p>
  457. <p>I’ll give you a quick example.</p>
  458. <p>When people do pair programming, their goals are usually some subset of these: </p>
  459. <ul>
  460. <li>focus </li>
  461. <li>avoiding silos </li>
  462. <li>code review </li>
  463. <li>onboarding </li>
  464. <li>cross-training </li>
  465. <li>fewer rabbit holes </li>
  466. </ul>
  467. <p>There are other ways to get all those things.</p>
  468. <p>So far, these are just the garden-variety problems with agile adoption that everyone’s been talking about for years. Let’s move on to the less-obvious problems.</p>
  469. <p>To find agile’s non-obvious problems, so we can start to see why heterogenous teams have trouble, let’s take a peek underneath the surface of the obvious problems.</p>
  470. <p>Let’s start with "very few people can pair that much."</p>
  471. <p>For many years, I was a pair programming evangelist. Between that &amp; my consulting work, I’ve met lots of people who tried pair programming and hated it. Some of them had paired for months, with different people, on different schedules, &amp; still couldn’t find a modality they liked.</p>
  472. <p>These people came from many different genders &amp; races. Some were introverted; some weren’t. What they all had in common wasn’t obvious to me for a long time...until recently, it was.</p>
  473. <p>They’re all usually on the downward side of one or more <em>power dynamics</em> in their pairs.</p>
  474. <p>Power dynamics in pairing is a subject that rarely comes up, at either the macro (community discussion) or micro (team discussion) levels. First let’s talk about what a power dynamic is, and then we can look at how it manifests in a pair.</p>
  475. <p>A power dynamic is behavior in an interaction driven by a hierarchical relationship between the participants. This hierarchical relationship can be formal (manager-report, or senior-junior) but more often is informal (based on race, gender, background, etc.).</p>
  476. <p>Informal power dynamics based on characteristics that have historically been subject to structural oppression turn around &amp; mimic that structural hierarchy. Men are more powerful than other genders; white people are more powerful than other races. And so forth.</p>
  477. <p>Note that "more powerful" in this context doesn’t mean any kind of formal power; men are not officially more powerful than other genders.</p>
  478. <p>The power I’m talking about here is simply the power to <em>ignore the dynamic completely</em>.</p>
  479. <p>People on the upward side of a power dynamic are free to pretend the dynamic doesn’t exist, and indeed, many times as children they’re told that that’s what they should do. "Don’t see color! Don’t see gender!"</p>
  480. <p>Even as adults, we get messages that sometimes suggest ignoring power dynamics is the right way to go. For example, I often see women asking men to treat them the same way that they, the men, treat other men at work.</p>
  481. <p>The trouble with ignoring a power dynamic when you’re on the upward side is that in doing so, you <em>reinforce</em> the dynamic, even though in many situations (like pair programming) neutralizing it would be better.</p>
  482. <p>That’s because from the upward side, you need to take real action to level the playing field. Due to the inherent nature of these power dynamics, folks on the upward side have do it. They are more powerful &amp; better resourced, and IMO it is their moral responsibility.</p>
  483. <p>When you’re on the upward side of a power imbalance &amp; you want to level the field, ignoring (or denying) the tilt doesn’t work. And if you place the burden on the downward side folks, you’re asking them to both walk uphill AND figure out how to distribute power they don’t have.</p>
  484. <p>Now in any given pair of people, multiple power dynamics are in play, and figuring out who is "most powerful" is not only pointless - it’s impossible. You can’t just sum them. Just like with oppression generally (of which this is a tiny piece), power dynamics are intersectional.</p>
  485. <p>Common power dynamics in play in a pair programming situation (low - high): </p>
  486. <ul>
  487. <li>junior - senior </li>
  488. <li>"wrong" background - "right" background </li>
  489. <li>learning developer - teaching developer </li>
  490. <li>feminine - masculine </li>
  491. <li>people of color - white folks </li>
  492. <li>women &amp; other genders - men</li>
  493. </ul>
  494. <p>As a white person, I think it sucks that the race dynamic that I’m on the upward side of exists, and I want to neutralize it as best I can. That means I need to actively work against it.</p>
  495. <p>But say I’m pairing with a black man who is technically expert in the problem we’re working on. Do these power dynamics cancel each other out? Can we go back to ignoring? </p>
  496. <p>Nope. As you may have figured out by now, power dynamics are something EVERYONE has to keep in mind.</p>
  497. <p>They are, as the name suggests, dynamic. They shift and mutate and change in prominence, often even over the course of one interaction.</p>
  498. <p>Three questions remain:</p>
  499. <ol>
  500. <li>What does "keeping them in mind" mean? </li>
  501. <li>How do we neutralize the ones we’re on the upper side of? </li>
  502. <li>What does this have to do with homogeneity in agile? (I promise we’re getting there)</li>
  503. </ol>
  504. <p>People who are on the upward side of a power dynamic often don’t even notice it’s there. Even more concerning is the fact that if they’ve been conditioned to think the playing field is already level (i.e., a ’meritocracy’) then they’ll often deny any such tilt exists.</p>
  505. <p>These denials are internalized often even by the folks who are running uphill. The place where you can see the tilt of the field is in broad statistical surveys: the pay gap. The wealth gap. Corporate diversity numbers. Promotion statistics. Glass ceilings &amp; cliffs.</p>
  506. <p>That’s the macro level. At the micro level, keeping these dynamics in mind and trying to neutralize the ones you’re on the upward side of is a tricky and complicated skill. Here are a few rubrics I’ve used over the years, that may help you get started:</p>
  507. <ol>
  508. <li>The more dynamics you’re on the upward side of, the more you take cues from your pair. Let them speak first. Be mindful of interrupting. Catch your reactions to their words on the way out, &amp; do a post-processing pass to consider whether your reaction is due to the dynamic.</li>
  509. <li>Think ahead of time of what dynamics might exist, and think carefully about where you are relative to each other in those dynamics. The list above is a good start, but there are many others: national origin, native language, external signs of religion, editor preference... (Seriously - the textual editor folks [vim, emacs, etc.] constantly place themselves above IDE users.) There’s also preferred language (woe be to you as a PHP developer coming into a shop that does basically anything else), &amp; location in the stack (HTML/CSS is less prestigious). There’s also role - developers tend to place themselves above designers, for example, which means as a dev, even if you don’t think designers are less-than, when you’re pairing with a designer you should be mindful of that dynamic.</li>
  510. <li>When your pair doesn’t reciprocate (i.e., talks over you, thinks their way is always correct, has reactions that would be different with someone else), one way to neutralize that is to demonstrate a power dynamic where you’re on the upward side, &amp; they’re on the downward side. This avenue isn’t always available, though - there may legitimately be no power dynamics that work that way, or there may be no way to demonstrate them. And now we come to why this practice is hard with a heterogenous team. Pairing has nothing to say about how to structure an interaction to avoid taking unfair advantage of power dynamics. One of its basic assumptions is that everyone feels empowered to contribute. When this is true, pairing is amazing. When it’s not, it’s a nightmare.</li>
  511. </ol>
  512. <p>Now ask yourself, who is it who always feels empowered to contribute? Who sees no need for further structure the mitigate the effects of power dynamics? Who, indeed, is most likely to deny such power dynamics even exist?</p>
  513. <p>At the micro level, pair programming can work as a practice on a heterogenous team - as long as you put in place further structure to mitigate the effects of these interpersonal power dynamics. But at the macro level, this is a fatal flaw.</p>
  514. <p>Because without further structure, the folks on the downside of those dynamics when they pair program feel constantly watched, judged, and steamrolled. No wonder they quit. No wonder I was only woman #2 out of 45 developers at Pivotal SF when I joined (&amp; the other was an intern).</p>
  515. <p>They’d had women developers before, but they had all quit. I managed to stay, because pairing worked really well with my brain, and because I derived some power from my public presence that caused most men to reconsider how they worked with me.</p>
  516. <p>That’s how pair programming fails heterogenous teams - by making assumptions that are really only true for people very similar to the practice’s originators.</p>
  517. <p>And then, of course, by having the originators EVEN TODAY deny that agile’s assumptions aren’t true for everyone.🙄</p>
  518. <p>For every practice, there’s a long story like this. People pushed back hardest yesterday on TDD - could driving your code with tests possibly be related to power dynamics?</p>
  519. <p>*Spoiler alert: YES😅</p>
  520. <p>One reason people like TDD is that you end up with a very nice set of self-documenting tests. Sounds great, right?</p>
  521. <p>But who exactly is this "self"? Not everyone understand code the same way. There are always assumptions built into this "self-documentation" about how the developer writing them wants to be communicated to.</p>
  522. <p>My tests, for example, tend to start at the outside ("what happens if you just call this method with no arguments?") and work their way cyclically inside, towards the specific functionality I’m driving out.</p>
  523. <p>Over the years, many men I’ve paired with have wanted to jump right into the specifics, and put all the other stuff at the bottom. They resist starting with what, eventually, is likely an error case.</p>
  524. <p>They argue that people expect the basic functionality to be at the top, like in a README. For me, however, I’d rather read the whole thing like a document, and understand the journey. I want a narrative. They want bullet points.</p>
  525. <p>This is a classically gendered split. Not every man wants bullet points, and not every woman wants a narrative, but statistically this split exists everywhere - in literature, in scientific writing, even in journalism.</p>
  526. <p>So who’s right? Neither of us, fully.</p>
  527. <p>But which is the standard form? The one men have an easier time with.</p>
  528. <p>Another aspect of TDD that is often emphasized is that this lets you write code "the right way," i.e., with tests, high quality, etc. How could that possibly be related to power dynamics? 🤔</p>
  529. <p>I’m glad you asked! It’s well-established that men taking the time to do things "the right way" are perceived as skilled, while women taking the time to do things "the right way" are perceived as incompetent (taking extra time for a simple task).</p>
  530. <p>In fact, current research suggests that this tendency travels across all the power dynamics - race, experience level, etc.</p>
  531. <p>But when the originators of this practice came up with it, they didn’t need to think about that, because they were all white men. There was no difference in how taking extra time to do it right was perceived.</p>
  532. <p>Neither the specific practice of TDD, nor the agile philosophy behind it, says anything about how to counter this perception. So people on the downward side fo the dynamics feel (correctly) that they’re trying to do the right thing but their contributions aren’t as valued.</p>
  533. <p>Again - white men can be completely ignorant of this dynamic, since it doesn’t affect them. When other people point it out, they often say something along the lines of "you’re making that up" or "you’re covering for your own incompetence."</p>
  534. <p>(See also: my mentions. Lots of "stop making excuses" ridiculousness. They don’t particularly bother me, because I know I can run circles around any of them. But when I was less confident, earlier in my career, I would have believed them.)</p>
  535. <p>A heterogenous team gives you something critical - experience on the downward side of important power dynamics. Provided they have good management, such a team can construct practices and process and software that doesn’t make the same assumptions of homogeneity.</p>
  536. <p>But that’s not where agile came from, nor eXtreme Programming. They came from homogenous teams composed of individuals largely on the upward side of important power dynamics. </p>
  537. <p>We don’t need to totally bin them, but we do need to reimagine them.</p>
  538. <p>That’s all I have to say right now, but know that every single agile practice has something like this behind it.</p>
  539. <p><cite><em><a href="https://twitter.com/sarahmei/status/990968833547497472">Sarah Mei on Twitter</a></em></cite></p>
  540. </blockquote>
  541. <p>Very eye-opening (mind-opening? heart-opening?!) thread by Sarah Mei, everybody in my filtered bubble is focusing on the agile/XP stuff but what I find interesting is that notion of <em>power dynamics</em> and how it affects our work. To go beyond that topic, let’s rephrase the latest sentence:</p>
  542. <blockquote>
  543. <p>know that every single <strong>relationship</strong> has something like this behind it.</p>
  544. </blockquote>
  545. <p>My comprehension of agility is that it tries to given some insights on why and how we can try to collaborate atop of these differences. It’s imperfect and it will never be because of the complexity of human nature. Each team should adapt and share its knowledge acquired in a particular context to <em>inspire</em> others (not dictate or patronize or blame or whatever). This is what we are good at: experimenting, reporting, iterating. And that’s why it is so valuable to get feedback/testimony like this from a particular point of view. Thanks.</p>
  546. <p>It especially gave me some clues on why sometimes pairing doesn’t fit. I had a mixed feeling about that, now I have a concept and a label to put on it :-).</p>
  547. <p><em>Note: pairing 8 hours a day looks inadequate to my capacities, I’m exhausted after only 2! If I joined a team which has these practices we would have to discuss and adapt (from both sides) but that’s another story.</em></p>
  548. </article>
  549. <nav>
  550. <p>
  551. <a rel=prev href="/david/stream/2018/05/01/">← Word-of-mouth</a> | <a href="/david/stream/2018/" title="Retour à la liste complète">↑</a> | <a rel=next href="/david/stream/2018/05/03/">Worse place →</a>
  552. </p>
  553. </nav>
  554. <aside>
  555. <p>
  556. Other articles in English:
  557. <a href="/david/blog/2018/caching-links/">On caching links</a>,
  558. <a href="/david/blog/2018/bushcraft-retrospective/">Bushcraft retrospective</a>,
  559. <a href="/david/blog/2018/into-the-raft/">Into the Raft</a>,
  560. <a href="/david/blog/2018/into-the-bugs/">Into the Bugs</a>,
  561. <a href="/david/blog/2018/meritocracy-crisis/">Meritocracy crisis</a>,
  562. <a href="/david/blog/2018/seller-teacher-wise/">The Seller, the Teacher and the Wise</a>,
  563. <a href="/david/blog/2018/into-the-good/">Into the Good</a>,
  564. <a href="/david/blog/2018/into-the-mice/">Into the Mice</a>,
  565. <a href="/david/blog/2018/into-the-camp/">Into the Camp</a>,
  566. <a href="/david/blog/2018/into-the-wind/">Into the Wind</a>,
  567. <a href="/david/blog/2018/into-the-snow/">Into the Snow</a>,
  568. <a href="/david/blog/2018/into-the-cold/">Into the Cold</a>,
  569. <a href="/david/blog/2017/async-python-frameworks/">Async Python Frameworks</a>,
  570. <a href="/david/blog/2017/distributed-teams/">Distributed teams</a>,
  571. <a href="/david/blog/2017/into-the-wild/">Into the Wild</a>,
  572. <a href="/david/blog/2017/without-javascript/">Without JavaScript</a>,
  573. <a href="/david/blog/2017/inclusive-python/">Inclusive Python</a>,
  574. <a href="/david/blog/2017/micro-cultures-governance/">Micro-cultures and governance</a>,
  575. <a href="/david/blog/2017/resilient-web-tools/">Resilient Web and Tools</a>,
  576. <a href="/david/blog/2017/bitcoin-energy/">Bitcoin and energy</a>,
  577. <a href="/david/blog/2016/team-building/">Team building</a>,
  578. <a href="/david/blog/2016/inclusive-developer/">Inclusive developer</a>,
  579. <a href="/david/blog/2016/cultural-intimacy/">Cultural Intimacy</a>,
  580. <a href="/david/blog/2016/tools-teams/">Tools and teams</a>,
  581. <a href="/david/blog/2016/senior-developer/">Senior developer</a>,
  582. <a href="/david/blog/2016/slow-data/">Slow Data</a>,
  583. <a href="/david/blog/2016/inclusive-communities/">Inclusive communities</a>,
  584. <a href="/david/blog/2016/delivery-values/">Delivery and value(s)</a>,
  585. <a href="/david/blog/2016/collaboration-debt/">Collaboration debt</a>,
  586. <a href="/david/blog/2016/communities-leadership/">Communities and leadership</a>,
  587. <a href="/david/blog/2016/specifications-apis/">Specifications and APIs</a>.
  588. Oh, and most of <a href="/david/stream/2018/">the 2018 thoughts</a>.
  589. </p>
  590. </aside>
  591. <nav>
  592. <p>
  593. <abbr title="Lieu de vie et de potentielles rencontres actuel">Montréal</abbr> ·
  594. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Contact</a> ·
  595. <a href="http://larlet.com" title="Identité professionnelle">[Travailler ensemble ?]</a> ·
  596. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">Hébergeur</abbr> ·
  597. <a href="/david/log/" title="S’abonner aux publications via RSS">Flux</a>
  598. </p>
  599. </nav>
  600. <script>
  601. /* Service workers */
  602. if (navigator.serviceWorker) {
  603. window.addEventListener('load', function () {
  604. var selector = 'a[href^="/david/cache/"], a[rel=prev], a[rel=next]'
  605. function sendLinks (selector) {
  606. var links = [].slice.call(document.querySelectorAll(selector)).map(function (link) {
  607. return link.getAttribute('href')
  608. })
  609. links.push(location.pathname) // Put the current page in cache too.
  610. navigator.serviceWorker.controller.postMessage({ links: links })
  611. }
  612. navigator.serviceWorker.getRegistration()
  613. .then(function (registration) {
  614. if (!registration || !navigator.serviceWorker.controller) {
  615. return navigator.serviceWorker.register('/serviceworker.js')
  616. .then(navigator.serviceWorker.ready)
  617. .then(function () {
  618. console.log('[ServiceWorker] Ready to go!')
  619. })
  620. .catch(console.error.bind(console))
  621. } else {
  622. console.log('[ServiceWorker] Send links via registration')
  623. sendLinks(selector)
  624. }
  625. })
  626. navigator.serviceWorker.addEventListener('controllerchange', function () {
  627. console.log('[ServiceWorker] Send links via controller change')
  628. sendLinks(selector)
  629. })
  630. navigator.serviceWorker.addEventListener('message', function (event) {
  631. var link = document.querySelector('a[href="' + event.data.link + '"]')
  632. if (event.data.status && link) {
  633. link.style.backgroundColor = '#2d7474'
  634. link.style.color = '#f0f0ea'
  635. link.setAttribute('title', 'Put in cache for offline use')
  636. }
  637. })
  638. })
  639. } else {
  640. console.warn('[ServiceWorker] No cache for old browsers.')
  641. }
  642. </script>