Coordinando a los Voluntarios
Conseguir que la gente se ponga de acuerdo sobre cuales son
las necesidades de un proyecto, y trabajar en la misma dirección
para llevarlas a cabo, requiere de algo más que un ambiente de trabajo
genial sin disfunciones visibles. Requiere una, o varias personas,
que coordinen diligentemente a toda la gente involucrada en el proyecto.
Es posible que coordinar voluntarios no sea un arte tecnológico como
lo pueda ser la programación, pero como cualquier arte puede mejorarse
a través del estudio y la práctica.
Este capítulo es un cajón de sastre de técnicas para coordinar
voluntarios. Se nutre, quizá más intensamente que capítulos anteriores,
en el proyecto Subversion, en parte porque yo trabajaba en dicho proyecto
mientras escribía esto y tenía información de primera mano, y en parte
porque es más aceptable tirar piedras sobre mi propio tejado que sobre
el tejado de otro. No obstante, también he sido testigo de las consecuencias
que ha tenido aplicar sobre otros proyectos (y las consecuencias de no
hacerlo) las recomendaciones que se exponen a continuación. Siempre que
sea políticamente correcto dar detalles de otros proyectos, así lo haré.
Hablando de política, este momento es tan bueno como cualquier otro
para inspeccionar en detalle la susodicha palabra maldita. Muchos
ingenieros hablan de política como si no fuera con ellos; "Yo
me centro en la mejor para el proyecto, pero Ella no
deja de poner pegas por razones políticas." Pienso que dicho distanciamiento
de la política (o por lo que se piensa que es la política) es especialmente
significativo entre los ingenieros, porque se los educa para pensar que
siempre hay razones objetivas para determinar que unas soluciones son
superiores a otras. Por tanto, cuando alguien actúa con motivaciones
aparentemente externas al proyecto (p.ej. solidificar la propia posición de
influencia en el proyecto, disminuir la influencia de otros, chalaneos
descarados, o evitar herir los sentimientos de alguien) otros participantes
del proyecto pueden molestarse. Por supuesto, esto raramente evita que
ellos se comporten de la misma manera cuando sus propios intereses se ven
amenazados.
Si consideras que la "política" es una palabra sucia, y tienes esperanzas
de mantener tu proyecto libre de ella, mejor que abandones ahora mismo.
La política es algo que surge inevitablemente cada vez que un grupo de personas
han de cooperar en la gestión de recursos compartidos. Es de lógica que,
cada vez que una persona toma una decisión, ésta se vea influenciada por
cómo va a afectar a su futuro personal en el proyecto. Después de todo,
si tienes confianza en tu juicio y habilidades, como sucede con la mayoría
de programadores, entonces una posible pérdida de influencia sobre el
proyecto podría ser considerada, en cierta manera, como un aspecto técnico
a tener en cuenta. Razonamientos similares se pueden aplicar a comportamientos
que, en apariencia, sean "pura" política. De hecho, no existe tal cosa como
la "pura política"; para empezar, porque como todas las acciones tienen múltiples
consecuencias en la vida real la gente adquiere conciencia política. La política,
al final, simplemente reconoce que todas las
consecuencias de nuestras decisiones han de tenerse en cuenta. Si decisiones
concretas llevan el proyecto por un camino que la mayoría considera
técnicamente correcto, pero dicha decisión conlleva un cambio en el
equilibrio de influencias del proyecto aislando a figuras clave del mismo,
entonces hemos de dar igual grado de importancia a ambas consecuencias.
No hacerlo así, no sólo no sería juicioso, sino que sería una actitud
corta de miras.
Por tanto, mientras leas los consejos que siguen a continuación,
y mientras trabajas en tu propio proyecto, recuerda que no hay
nadie que esté por encima de la política. Dar la
impresión que se está por encima de ella es simplemente otra estrategia
política más y, por cierto, en ocasiones una muy útil, pero nunca refleja
la realidad. La política es sencillamente lo que sucede cuando la gente
no está de acuerdo en algo, y los proyectos que acaban con éxito son
aquellos capaces de desarrollar un mecanismo político para gestionar
los desacuerdos de forma constructiva.
Conseguir el Máximo de los Voluntarios
Por qué los voluntarios trabajan en proyectos de software libre?
Esta cuestión fue estudiada en detalle, arrojando
interesantes resultados, en un ensayo de Karim Lakhani y Robert G. Wolf,
tituladoPor qué los Hackers Hacen lo que Hacen: Comprensión
de la Motivación y el Esfuerzo en Proyectos de Código Libre/Abierto. Ved
.
Cuando se les pregunta, muchos dicen que lo hace por que quieren
producir buen software, o por que quieren involucrarse en arreglar errores
que son importantes para ellos. Pero estas razones no acostumbran a ser toda
la verdad. Después de todo ¿podrías imaginarte a un voluntario permaneciendo
en un proyecto a pesar de que nadie, nunca, le dirigiera un palabra de aprecio
por su trabajo, o se le escuchara en las discusiones? Claro que no.
Claramente, la gente gasta su tiempo en el software libre por razones que
van más allá del deseo abstracto de producir buen código. Comprender las
verdaderas motivaciones de los voluntarios te ayudará a organizar las cosas
de manera que puedas atraerlos y que no se vayan. El deseo de producir buen
código puede estar entre esas motivaciones, junto con el desafío y valor educativo
que supone trabajar en problemas difíciles, pero los seres humanos tienen el
deseo natural de trabajar con otros humanos, y el de dar y recibir respeto
a través de actividades colectivas. Grupos cooperando en tareas colectivas
deben desarrollar normas de comportamiento tales que el prestigio sea adquirido
,y mantenido, a través de acciones que ayuden a la consecución de las
metas del grupo.
Esas normas no aparecen por sí solas. Por ejemplo, en algunos proyectos
(desarrolladores con experiencia en código abierto podrían mencionar varias de
memoria) la gente piensa que se gana prestigio por enviar largos mensajes
frecuentemente. No llegan a esta conclusión por casualidad, llegan a ella
porque son recompensados con respeto por crear largos e intrincados argumentos,
independientemente de que estos ayuden al proyecto. A continuación se explican
algunas técnicas para crear una atmósfera en la que se pueda adquirir prestigio
a través de acciones constructivas.
Delegar
Delegar no simplemente una forma de distribuir la carga de trabajo,
sino que también es una herramienta política y social. Piensa en todas
las consecuencias que tiene pedir a alguien que haga algo. El efecto más
evidente es que, si acepta, esa persona hace el trabajo y tú no. Pero otro
efecto es que esa persona toma consciencia de que tú confías en él para
realizar la tarea. Además, si haces la petición en un foro público,
también aprecia que el resto de participantes son conscientes de la
confianza que ha sido depositada en él. También es posible que se sienta
presionado a aceptar, por tanto has de preguntar de manera que le sea
fácil declinar la oferta si realmente no quiere aceptarla. Si la tarea
requiere coordinarse con otros participantes del proyecto, entonces
le estás pidiendo un mayor grado de compromiso con el proyecto, crear
lazos que no se hubieran creado de otra forma y, quizá, convertirse en
una fuente de autoridad y algunos subdominios del proyecto. La responsabilidad
adquirida puede ser agobiante, o puede llevarle a involucrarse en más
áreas del proyecto gracias a un renovado sentimiento de compromiso.
Debido a todos estos posibles efectos, a menudo tiene sentido pedir
a otro que haga algo incluso cuando sabes que tú lo podrías hacer mejor
o más rápido. Por supuesto, siempre hay momentos en que delegarás únicamente
por motivos de eficiencia; quizá el coste de oportunidad de hacer una
tarea tú mismo es demasiado alto debido a que podrías dedicarte a hacer
algo más importante para el proyecto. Pero incluso cuando el argumento del
coste de oportunidad no existe, aún así es posible
que pidas a otro hacer una tarea simplemente porque quieres involucrar más
a una determinada persona en el proyecto, incluso si eso significa que
has de supervisar su trabajo al principio. Esta técnica también funciona
al revés; si ocasionalmente te presentas voluntario para hacer un trabajo
que alguien no quiere, o no tiene tiempo de hacer, te ganarás su confianza
y su respeto. Delegar y sustituir no tiene que ver simplemente con finalizar
tareas; tiene mucho que ver también con aumentar el grado de compromiso de
la gente con el proyecto.
Distingue claramente entre pedir y asignar
En ocasiones es lógico esperar que una persona aceptará de buen
grado una tarea en particular. Por ejemplo, si alguien introduce un error
en el código, o envía código que incumple de forma clara con las directrices
del proyecto, debería ser suficiente con mencionar el problema y esperar
que el responsable de dicho código se haga cargo. Pero hay otras situaciones
donde no está nada claro que puedas esperar que alguien haga cargo. La
persona podría hacer lo que le pides, o quizá no. Como a nadie le gusta que
se dé por hecho que va a obedecer, has de ser consciente en todo momento de
cual de estas dos situaciones estás tratando y, en función de la misma,
medir tus palabras a la hora de solicitar una tarea.
Algo que casi siempre sienta mal es que te pidan hacer algo como si
fuera tu responsabilidad cuanto tu piensas que no es así. Por ejemplo,
asignar nuevos problemas en el código es terreno abonado para este tipo de
situaciones. Los participantes de un proyecto normalmente saben quien es
experto en cada área, así que cuando un error en el código aparece, habrá
normalmente una o dos personas en las que todo el mundo piensa que podrían
arreglar el problema rápidamente. No obstante, si asignas la tarea a una
de estas personas sin pedirles permiso, dicha persona podría sentirse
incómoda y forzada a encargarse de la tarea, podría sentir que se espera
mucho de ella y que, de alguna forma, está siendo castigada por sus
conocimientos y experiencia. Después de todo, la forma en la que uno adquiere
dichas habilidades es corrigiendo código, así que ¡quizá debería ser otro
el que lo corrija esta vez! (Cabe mencionar que los gestores automáticos de
errores que asignan tareas en función del tipo de error, reducen este tipo
de conflictos porque todo el mundo sabe que las tareas se asignan de forma
automática y que nadie espera nada de la persona a la que se ha asignado
la tarea.)
Aunque lo deseable sería distribuir la carga de trabajo tan
equitativamente como fuera posible, hay ocasiones en las que simplemente
quieres que puede arreglar el problema más rápidamente haga el trabajo.
Dado que no puedes permitirte establecer un diálogo para todas y cada
una de las tareas que se han de asignar ("¿Te importaría echarle un vistazo
a este error?" "Sí." "Vale, entonces te asigno la tarea a ti." "Vale."),
deberías siempre asignar tareas en forma de petición, sin ejercer presión
alguna. Casi todos los gestores de errores permiten asociar comentarios
a la tarea asignada. En dicho comentario podrías decir algo así:
Tarea asignada a ti, jaleatorio, porque tu eres la persona
más familiarizada con este código. No te preocupes si no puedes
hacerte cargo de la tarea por el motivo que sea. (En cualquier
caso hazme saber si preferirías no recibir más tareas en el futuro.)
Así se distingue claramente la petición de
la tarea de la aceptación de la misma. El mensaje no
sólo va dirigido a la persona a la que se pide la tarea; informa a todo el
grupo del área de experiencia de dicho miembro y, además, deja claro a todos
que dicha persona es libre de aceptar o rechazar la tarea.
Supervisar después de delegar
Cuando le pidas a alguien que haga algo, recuerda que los has hecho
y supervisa con él la tarea pase lo que pase. La mayoría de peticiones
se hace en foros públicos más o menos de la siguiente manera "¿Podrías
encargarte de X? Dinos algo en cualquier caso. En caso de que no puedas
no pasa nada, pero háznoslo saber." Pueden responder, o no, a tu petición,
pero si te responden, y la respuesta es negativa, el proceso se cierra y
tendrás que buscar alternativas para llevar a cabo la tarea X. Si la
respuesta es positiva entonces vigila como progresa el trabajo y haz
comentarios sobre el mismo (todo el mundo trabaja mejor cuando sabe que hay
alguien que aprecia su trabajo). Si no hay respuesta después de unos días,
pregunta de nuevo, o comenta en el foro que nadie a respondido y que
buscas a alguien que ses encargue de la tarea, o simplemente hazlo tú pero,
en cualquier caso, asegúrate de comentar que no recibiste respuesta alguna
a tu petición"
El motivo de hacer pública la falta de respuesta no
es para humillar a la persona a la que se le hizo la petición, y cuando
menciones el tema lo has de hacer de forma que esto quede claro. El propósito
es de dejar claro que sigues la pista de todo lo que pides, y que reaccionas
ante las respuestas que recibes, o no, a tus peticiones. Esta actitud hace
que sea más probable que la gente acepta la tarea la próxima vez, y esto es
así porque se darán cuenta (aunque sea inconscientemente) que es probable
que aprecies cualquier trabajo que hagan debido a que prestas atención a
detalles tan pequeños como el que alguien no responda a una petición.
Fíjate en lo que se interesa la gente
Otra cosa que pone a la gente contenta es que te fijes en sus intereses;
en general, cuantos más aspectos recuerdas de la personalidad de alguien, más
a gusto se encontrará dicha persona, y se interesará más por trabajar en grupos
de los que tú seas parte.
Por ejemplo, había una clara diferencia en el proyecto Subversion entre la
gente que quería llegar pronto a una versión final 1.0 (cosa que finalmente hicimos),
y la gente que principalmente quería añadir nuevas funcionalidades y trabajar
en problemas interesantes sin importarles mucho cuando estaría lista la versión 1.0.
Ninguna de estas dos posturas es mejor o peor que la otra; simplemente reflejan
dos tipos distintos de desarrolladores, y ambos realizan mucho trabajo en el proyecto.
Pero aprendimos rápidamente que era vital no asumir que el
interés por tener una versión 1.0 era compartido por todos. Las comunicaciones
electrónicas pueden ser muy engañosos; puedes pensar que hay un ambiente de propósito
común cuando, en realidad, dicho propósito sólo es compartido por la gente con
la que tú has estado hablando, mientras otras personas tienen prioridades completamente
distintas
Cuanto más consciente seas de lo que la gente quiere sacar del proyecto, más
eficientemente podrás pedirles cosas. Simplemente demostrando comprensión por lo que
quieren, sin demandar nada por ello, tiene una utilidad per se, puesto que confirma
a cada uno que no es una simple partícula de una masa informe.
Halagos y Críticas
Halago y crítica no son antónimos, de hecho, en muchos aspectos son
muy similares. Ambas son muestras de atención, y son más efectivas cuando
son específicas que cuando son genéricas. Ambas deben hacerse con metas
específicas en mente. Ambas pueden diluirse por el abuso; halaga mucho o
demasiado y tus halagos perderán valor, y lo mismo sirve para las críticas
aunque, en la práctica, las críticas provocan reacciones que las hacen
mucho más resistentes a la devaluación.
Un importante aspecto de la cultura tecnológica es que la detallada y
desapasionada crítica a menudo se toma como una especia de alago (como se
vio en
en ), esto se debe a la implicación
de que el trabajo en cuestión vale la pena ser analizado. En cualquier caso,
ambos aspectos; detallada y desapasionada
han de cumplirse para que esto se cumpla. Por ejemplo, si alguien hace
algún cambio chapucero en el código, es inútil (y de hecho perjudicial)
comentar el asunto simplemente diciendo "Eso es una chapuza". El ser un
chapuzas es, al final, una característica de la persona,
no de su trabajo, y es importante mantener tu atención enfocada en el
trabajo hecho. Es mucho más eficiente describir todas las cosas equivocadas
que se han introducido al realizar el cambio, y hay que hacerlo con
tacto y sin malicia. Si fuera el tercer o cuarto cambio descuidado de la
misma persona, entonces lo más apropiado mencionar el hecho, después de la
crítica sobre el trabajo realizado, y de nuevo sin ningún signo de enfado,
para así dejar claro que dicho patrón de comportamiento es evidente.
Si alguien no mejora después de las críticas, la solución no es
criticar más, o hacerlo más duramente. La solución consiste en que el grupo
retire a dicha persona del trabajo en el que es incompetente de forma que
se hiera lo menos posible los sentimientos de la misma, leed
al final del capítulo
unos ejemplos. En cualquier caso, este no es un hecho frecuente.
La mayoría de gente responde muy bien a las críticas que son específicas,
detalladas, y que contienen una clara (aunque sea entre líneas) indicación
de que se espera una mejora.
Las alabanzas no herirá la sensibilidad de nadie, por supuesto, pero eso
no significa que se deba usar con menos cuidado que las críticas. Las alabanzas
son una herramienta; antes de usarla pregúntate por qué
quieres usarla. Como regla, no es una buena idea alabar a alguien por hacer
lo que normalmente hace, o por acciones que son habituales y esperadas de
alguien que trabaja en grupo. Si hicieras eso, no será fácil saber cuando parar;
¿deberías alabar a todo el mundo por hacer lo habitual?
Al fin y al cabo, si te dejas a alguien se preguntarán por qué. Es mucho mejor
expresar alabanzas y gratitud ocasionalmente en respuesta a un esfuerzo
inusual, o inesperado, con la intención de fomentar dichos esfuerzos. Cuando
un participante parece haberse trasladado permanentemente a un estado de alta
productividad, debes ajustar tu nivel de alabanzas consecuentemente. Repetidas
alabanzas se acaban convirtiendo en algo sin significado alguno. En su lugar,
dicha persona deber sentir que su alto nivel de productividad se considera
normal y natural, y sólo trabajo que sobrepasa ese nivel debe ser significado.
Por supuesto, esto no quiere decir que las contribuciones de dicha persona
no deban ser reconocidas. Pero recuerda que si el proyecto se organiza
correctamente, todo lo que hace una persona es visible de todas formas, y por
tanto el grupo verá (y la persona implicada sabrá que el resto de miembros
lo ven también) todo lo que ella hace. También hay otras maneras de reconocer el
trabajo de alguien además de las alabanzas. Podrías mencionar de pasada, al
debatir sobre un tema, que dicha persona ha trabajado mucho en ese área y que
es experta en la misma. Podrías realizar consultas públicas a dicha persona sobre
el código o, quizá mejor, podrías utilizar su trabajo de forma ostensible para
que la persona pueda apreciar que la gente tiene confianza en los resultados de
su trabajo. Probablemente no es necesario hacer todas estas cosas de forma
calculada. Las personas que contribuyen notablemente lo saben y ocuparán una
posición de influencia de forma natural. Normalmente no hay que tomar medidas
explícitas para asegurar esto, a menos que sientas que, por cualquier motivo,
un miembro del grupo es poco valorado.
Prevén la Territorialidad
Ten cuidado con los participantes que intentan apropiarse la exclusividad
en ciertas áreas del proyecto, y con aquellos que parecen querer hacer todo
el trabajo en esas áreas hasta el punto de apropiarse del trabajo que otros
han comenzado. Dicho comportamiento puede parecer saludable al principio,
después de todo, a primera vista parece como si el individuo en cuestión
simplemente está tomando más responsabilidad, y mostrando una mayor actividad
en dichas áreas. A la larga, no obstante, dicho comportamiento es destructivo.
Cuando la gente ve señales de "no pasar" se apartan del proyecto. Esto conlleva
una visión más estrecha de esa área, y una mayor fragilidad de la misma puesto
se depende de la disponibilidad e un único desarrollador. Todavía peor, rompe
el espíritu de cooperación igualitaria del proyecto. En teoría, la ayuda de
cualquier desarrollador debe ser bienvenida en cualquier momento, y sobre
cualquier área. Por supuesto, en la práctica las cosas funciona de manera algo
diferente; la gente tiene áreas donde es más o menos influyente, y los inexpertos
habitualmente dejan que los expertos tomen las riendas en ciertos dominios
del proyecto. Pero la clave es que todo esto es algo voluntario; la autoridad
se gana mediante la competencia y conocimiento probado, y nunca debe ser
conquistada activamente. Incluso si la persona deseando la
autoridad es realmente competente, aún así es crucial que maneje esa
autoridad de manera informal, a través del consenso del grupo, y sin apartar
a nadie de colaborar en su área de influencia.
Por supuesto, rechazar o editar el trabajo de otro por motivos técnicos es
un asusto totalmente distinto. En este caso, el factor decisivo es el contenido
del trabajo, no quien actúa como portero. Podría suceder que la misma persona
realice la mayor parte de revisiones para un área particular, pero mientras no
evite que otros hagan su trabajo, las cosas deberían ir bien.
Para combatir cualquier territorialismo incipiente, o incluso la mera
apariencia del mismo, muchos proyectos han tomado medidas como la de prohibir
la inclusión del nombre del autor, o de los encargados elegidos, en el
código fuente. Yo estoy de acuerdo de todo corazón con esta práctica; la
utilizamos en el proyecto Subversion y es, más o menos, la política oficial
en la Apache Software Foundation. El miembro del ASF Sander Striker lo
explica de esta forma:
en la Apache Software Foundation desaconsejamos el uso
de entradas con el nombre del autor en el código fuente. Hay varias razones
para esto además de motivos legales. En el desarrollo en equipo se trata de
trabajar en grupo y tratar al proyecto en grupo. Dar crédito es bueno,
y debe hacerse, pero de alguna manera esta forma de actuar evita falsas
atribuciones, incluso cuando sólo son implícitas. No hay una directriz clara
de cuando se ha de añadir o quitar entradas con el nombre del autor; ¿Añades
tu nombre si cambias un comentario? ¿Cuando arreglas una sola línea de código?
¿Has de borrar el nombre de alguien cuando reestructuras el código y es diferente
al anterior en un 95%? ¿Qué haces con la gente que va tocando cada archivo,
cambiando lo mínimo para que su nombre aparezca en todas partes?
Hay mejores formas de dar crédito, y nosotros preferimos usar
esas. Desde un punto de vista técnico las entradas con el nombre del autor son
innecesarias; si quieres saber quién escribió una determinada línea de código
se puede consultar el sistema de control de versiones para averiguarlo. Además,
las entradas de autor acostumbran a estar caducadas; ¿Realmente quieres que
se pongan en contacto contigo por unas líneas de código que programaste
hace cinco años y estás contento de haberlas olvidado?
El corazón de la identidad de un proyecto lo forman los archivos con el
código fuente. Estos deben reflejar que la comunidad, como un todo, es responsable de
los mismos, y no deben dividirse en pequeños feudos.
La gente a veces defiende las entradas de autor en el código fuente
argumentando que dan crédito de forma visible a aquellos que han realizado más
trabajo. Hay dos problemas con este argumento. Primero, las entradas de autor
traen consigo la incómoda pregunta de cuánto trabajo se ha de realizar para
que tu nombre también aparezca en el archivo. Segundo, las entradas fusiona
la autoridad en un área con el crédito en la misma; haber hecho la mayor parte
del trabajo en un área no implica que se posea dicha área, pero es difícil,
sino imposible, evitar dicha implicación cuando hay nombres de personas
al comienzo de un archivo de código fuente. En cualquier caso, se puede saber
el autor del código a través del sistema de control de versiones u otros
métodos alternativos como los archivos de las listas de correos, de esta
forma no se pierde ninguna información al no permitir las entradas de autor
en el código fuente.
Si en tu proyecto se decide no permitir incluir entradas de autores
en el código fuente, asegúrate de no pasarte de la raya. Por ejemplo,
muchos proyectos tienen un área contrib/ donde se
almacenan pequeñas herramientas y scripts de ayuda, a menudo escritos
por gente que no están asociados con el proyecto de ninguna otra manera.
Para ese tipo de archivos está bien que se introduzca los nombres de los
autores porque ellos no están desarrollando el proyecto en sí. Por otro
lado, si una de estas herramientas comienza a ser alterada por otros
miembros del proyecto, puede que al final quieras trasladar dicha herramienta
a un lugar menos aislado y, suponiendo que el autor original aceptara,
borrar los nombres de los autores para que el archivo siga la política
del resto de archivos del proyecto. Si el autor original no se siente
a gusto con esta iniciativa se pueden alcanzar acuerdos, por ejemplo:
# indexclean.py: Borrar datos viejos del índice Scanley.
#
# Autor Original: K. Maru <kobayashi@yetanotheremailservice.com>
# Gestionado Ahora Por: The Scanley Project <http://www.scanley.org/>
# and K. Maru.
#
# ...
Pero, dentro de lo posible, es mejor evitar dichos compromisos, además,
la mayoría de autores están dispuestos a ser persuadidos puesto que se sienten
felices de que su contribución pase a ser parte integral del proyecto.
Lo importante es recordar que hay una continuidad entre el centro
y la periferia de cualquier proyecto. Los archivos del código fuente del
software son claramente centrales en el proyecto, y deben ser gestionados
por la comunidad en su conjunto. Por otro lado, herramientas accesorias, o
documentación, pueden ser el resultado del trabajo de un solo individuo, y lo
puede gestionar él solo aunque su trabajo esté asociado, en incluso
distribuido, con el proyecto. En cualquier caso, no hay necesidad de aplicar
la misma regla a todos los archivos siempre y cuando los recursos comunitarios
sean gestionados por todos, y no puedan convertirse en conto privado de nadie.
El Ratio de Automatización
Intenta evitar que los humanos hagan lo que pueden hacer las máquinas
en su lugar. Como regla general, automatizar una tarea común supone un
esfuerzo diez veces menor al esfuerzo que le supondría al desarrollador
realizar la tarea a mano. Para tareas muy frecuentes, o muy complejas, el
ratio puede ser veinte veces superior e incluso mayor.
Verte a ti mismo como a un "Director de Proyecto", en lugar de
como a un desarrollador, puede llegar a ser una actitud positiva. A veces,
algunos desarrolladores están demasiado enfrascados en su trabajo
a bajo nivel, esto no les permite tener una visión general del proyecto
y darse cuenta de que todo el mundo está desperdiciando mucho esfuerzo
en realizar tareas manualmente que podrían muy bien automatizarse.
Incluso aquellos que sí se dan cuenta, pueden no tomarse el tiempo
para resolver el problema, al fin el al cabo, el rendimiento de cada
individuo para realizar dicha tarea no es una carga demasiada onerosa,
nadie se siente lo suficientemente molesto como para hacer algo al
respecto. La automatización se hace atractiva cuando se tiene en cuenta
que, esa pequeña carga, se multiplica por el número de veces que cada
desarrollador ha de realizarla, y entonces ese
número se múltiplica por el número de desarrolladores.
Aquí estoy utilizando la palabra "automatización" con un sentido
muy amplio queriendo dar a entender, no sólo acciones repetitivas donde
una o dos variables cambian cada vez, sino también cualquier tipo de
infraestructura técnica que ayude a los humanos. La mínima automatización
estándar necesaria para llevar a cabo un proyecto en nuestros días fue
descrita en , pero cada proyecto
puede tener sus propios problemas especiales. Por ejemplo, un grupo
trabajando en la documentación quizá quiera una página web que muestre
las versiones más actualizadas del documento en todo momento. Como la
documentación se redacta normalmente en lenguajes del estilo de XML, puede
haber un paso de compilación, a menudo bastante intrincado, relacionado
con la creación de documentos para que puedan ser mostrados o bajados de
la red. Crear un página web donde esa compilación tenga lugar automáticamente
en cada envío puede ser bastante complejo y llevar mucho tiempo—pero
vale la pena, incluso si te lleva uno o más días configurarla. Los
beneficios globales de tener páginas actualizadas disponibles en todo
momento son enormes, incluso si el coste de no tenerlas
pueda parecer una simple molestia en un momento dado, para un desarrollador
cualquiera.
Seguir estos pasos no sólo elimina las pérdidas de tiempo, sino también
las obsesiones y frustraciones que aparecen cuando los humanos cometen errores
(inevitablemente lo harán) al intentar realizar procedimientos complicados
manualmente. Las tareas con múltiples pasos y operaciones deterministas son
el tipo de cosas para las que se inventaron las computadoras, y así dejamos que
los humanos hagan cosas más interesantes.
Comprobaciones Automáticas
Ejecutar pruebas automáticas es muy útil para cualquier proyecto de
software, pero especialmente para proyectos de código abierto porque las
pruebas automáticas (especialmente las pruebas de regresión) permiten que los
desarrolladores se encuentren a gusto a la hora de cambiara código en áreas
en las que no están familiarizados y, así, se favorece el desarrollo de
exploración. Como es muy difícil detectar fallos a simple vista—básicamente
has de adivinar dónde alguien puede haberse equivocado y realizar varios
experimentos para asegurarte de que no lo hizo—tener métodos
automáticos para detectar dichos errores ahorra muchísimo
tiempo. También hace que la gente se relaje a la hora de refactorizar
grandes franjas de código y, por lo tanto, contribuye a que el software
pueda ser gestionado a largo plazo.
Pruebas de Regresión
Por Pruebas de Regresión se entienden las
comprobaciones que se realizan para detectar errores que ya se han
reparado. El objetivo de las pruebas de regresión es reducir las
probabilidades de que los cambios en el código rompan el software de
forma inesperada. Cuando un proyecto de software crece y se complica,
las probabilidades de encontrarse dichos efectos secundarios crecen
al mismo paso. Un buen diseño puede reducir el crecimiento del ratio
de dicha probabilidad, pero no puede eliminar el problema completamente.
Como resultado de esta situación, muchos proyectos tienen una
colección de pruebas, un programa aparte que
ejecuta el software del proyecto en formas y maneras que se sabe producian
errores específicos con anterioridad. Cuando la colección de pruebas
consigue reproducir uno de estos errores, esto es conocido como
regresión, dando a entender que las modificaciones
de alguien han vuelto a recrear inesperadamente un error corregido
con anterioridad.
Ved también
.
Las pruebas de regresión no son un panacea. Por un lado funciona
bien para programas que tienen un estilo de interfaz de lineas de comando.
El software que se utiliza principalmente através de una interfaz gráfica
es mucho más difícil de utilizar mediante otro programa. Otro problema
radica en que la estructura misma de la colección de pruebas puede ser
muy compleja, con una curva de aprendizaje y cargas de mantenimiento
propias. Reducir esta complejidad es una de las cosas más útilies que
puedes hacer, incluso si ello implica una cantidad de tiempo considerable.
Cuanto más fácil sea añadir nuevas pruebas a la colección, más
desarrolladores lo harán, y menos errores sobrevivirán a la versión final.
Cualquier esfuerzo empleado en que la creación de pruebas sea sencilla
redundará con intereses en el desarrollo del proyecto.
Muchos proyectos siguen la regla "¡No rompas el código!"
, queriendo decir: no envíes cambios que hagan que sea
imposible compilar o ejecutar el software. Ser la persona que rompe el
código es normalmente causa de cierta vergüenza y burla. Proyectos con
colecciones de pruebas de regresión tienen amenudo una nueva regla
a modo de corolario: no envíes ningún cambio que hagan fallar las pruebas.
Dichos fallos son más fáciles de identificar si se realizan ejecuciones
automáticas cada noche de toda la colección de pruebas, con los resultados
enviados por email a los desrrolladores o a listas de correo dedicadas al
efecto; este es otro ejemplo de automatización que vale la pena.
La mayoría de los desarrolladores voluntarios están dispuestos a tomar el tiempo adicional para
escribir pruebas de regresión, cuando el sistema de pruebas es comprensible y
fácil de trabajar. Acompañar modificaciones con pruebas es entendido como
una responsabilidad de hacerlo, y es también una oportunidad fácil para la
colaboración: a menudo los desarrolladores dividen el trabajo para corregir un
fallo, uno de ellos corrige, y el otro escribe
el ejemplo de prueba. El segundo desarrollador puede terminar con más trabajo, y aunque
escribir un ejemplo de prueba es menos satisfactorio que corregir realmente el
fallo, es imprescindible que el conjunto de pruebas no haga la experiencia más
dolorosa de lo que debe ser.
Some projects go even further, requiring that a new test
accompany every bugfix or new feature. Whether
this is a good idea or not depends on many factors: the nature of the
software, the makeup of the development team, and the difficulty of
writing new tests. The CVS (cvs.nongnu.org/)
project has long had such a rule. It is a good policy in theory,
since CVS is version control software and therefore very risk-averse
about the possibility of munging or mishandling the user's data. The
problem in practice is that CVS's regression test suite is a single
huge shell script (amusingly named sanity.sh),
hard to read and hard to modify or extend. The difficulty of adding
new tests, combined with the requirement that patches be accompanied
by new tests, means that CVS effectively discourages patches. When I
used to work on CVS, I sometimes saw people start on and even complete
a patch to CVS's own code, but give up when told of the requirement to
add a new test to sanity.sh.
It is normal to spend more time writing a new regression test
than on fixing the original bug. But CVS carried this phenomenon to
an extreme: one might spend hours trying to design one's test
properly, and still get it wrong, because there are just too many
unpredictable complexities involved in changing a 35,000-line Bourne
shell script. Even longtime CVS developers often grumbled when they
had to add a new test.
This situation was due to a failure on all our parts to consider
the automation ratio. It is true that switching to a real test
framework—whether custom-built or off-the-shelf—would have
been a major effort.Note that there would be no need
to convert all the existing tests to the new framework; the two could
happily exist side by side, with old tests converted over only as they
needed to be changed. But neglecting to do so has
cost the project much more, over the years. How many bugfixes and new
features are not in CVS today, because of the
impediment of an awkward test suite? We cannot know the exact number,
but it is surely many times greater than the number of bugfixes or new
features the developers might forgo in order to develop a new test
system (or integrate an off-the-shelf system). That task would only
take a finite amount of time, while the penalty of using the current
test suite will continue forever if nothing is done.
The point is not that having strict requirements to write tests
is bad, nor that writing your test system as a Bourne shell script is
necessarily bad. It might work fine, depending on how you design it
and what it needs to test. The point is simply that when the test
system becomes a significant impediment to development, something must
be done. The same is true for any routine process that turns into a
barrier or a bottleneck.
Treat Every User as a Potential Volunteer
Each interaction with a user is an opportunity to get a new
volunteer. When a user takes the time to post to one of the project's
mailing lists, or to file a bug report, he has already tagged himself
as having more potential for involvement than most users (from whom
the project will never hear at all). Follow up on that potential: if
he described a bug, thank him for the report and ask him if he wants
to try fixing it. If he wrote to say that an important question was
missing from the FAQ, or that the program's documentation was
deficient in some way, then freely acknowledge the problem (assuming
it really exists) and ask if he's interested in writing the missing
material himself. Naturally, much of the time the user will demur.
But it doesn't cost much to ask, and every time you do, it reminds the
other listeners in that forum that getting involved in the project is
something anyone can do.
Don't limit your goals to acquiring new developers and
documentation writers. For example, even training people to write
good bug reports pays off in the long run, if you don't spend
too much time per person, and if they go on
to submit more bug reports in the future—which they are more
likely to do if they got a constructive reaction to their first
report. A constructive reaction need not be a fix for the bug,
although that's always the ideal; it can also be a solicitation for
more information, or even just a confirmation that the behavior
is a bug. People want to be listened to.
Secondarily, they want their bugs fixed. You may not always be able
to give them the latter in a timely fashion, but you (or rather, the
project as a whole) can give them the former.
A corollary of this is that developers should not express anger
at people who file well-intended but vague bug reports. This is one
of my personal pet peeves; I see developers do it all the time on
various open source mailing lists, and the harm it does is palpable.
Some hapless newbie will post a useless report:
Hi, I can't get Scanley to run. Every time I start it up, it
just errors. Is anyone else seeing this problem?
Some developer—who has seen this kind of report a
thousand times, and hasn't stopped to think that the newbie has
not—will respond like this:
What are we supposed to do with so little information?
Sheesh. Give us at least some details, like the version of
Scanley, your operating system, and the error.
This developer has failed to see things from the user's point of
view, and also failed to consider the effect such a reaction might
have on all the other people watching the
exchange. Naturally a user who has no programming experience, and no
prior experience reporting bugs, will not know how to write a bug
report. What is the right way to handle such a person? Educate them!
And do it in such a way that they come back for more:
Sorry you're having trouble. We'll need more information in
order to figure out what's happening here. Please tell us the
version of Scanley, your operating system, and the exact text of
the error. The very best thing you can do is send a transcript
showing the exact commands you ran, and the output they produced.
See http://www.scanley.org/how_to_report_a_bug.html for more.
This way of responding is far more effective at
extracting the needed information from the user, because it is written
to the user's point of view. First, it expresses sympathy:
You had a problem; we feel your pain. (This is
not necessary in every bug report response; it depends on the severity
of the problem and how upset the user seemed.) Second, instead of
belittling her for not knowing how to report a bug, it tells her how,
and in enough detail to be actually useful—for example, many
users don't realize that "show us the error" means "show us the exact
text of the error, with no omissions or abridgements." The first time
you work with such a user, you need to be specific about that.
Finally, it offers a pointer to much more detailed and complete
instructions for reporting bugs. If you have successfully engaged
with the user, she will often take the time to read that document and
do what it says. This means, of course, that you have to have the
document prepared in advance. It should give clear instructions about
what kind of information your development team wants to see in every
bug report. Ideally, it should also evolve over time in response to
the particular sorts of omissions and misreports users tend to make
for your project.
The Subversion project's bug reporting instructions are a fairly
standard example of the form (see ). Notice how they close with an
invitation to provide a patch to fix the bug. This is not because
such an invitation will lead to a greater patch/report
ratio—most users who are capable of fixing bugs already know
that a patch would be welcome, and don't need to be told. The
invitation's real purpose is to emphasize to all readers, especially
those new to the project or new to free software in general, that the
project runs on volunteer contributions. In a sense, the project's
current developers are no more responsible for fixing the bug than is
the person who reported it. This is an important point that many new
users will not be familiar with. Once they realize it, they're more
likely to help make the fix happen, if not by contributing code then
by providing a more thorough reproduction recipe, or by offering to
test fixes that other people post. The goal is to make every user
realize that there is no innate difference
between herself and the people who work on the project—that
it's a question of how much time and effort one puts in, not a
question of who one is.
The admonition against responding angrily does not apply to rude
users. Occasionally people post bug reports or complaints that,
regardless of their informational content, show a sneering contempt at
the project for some failing. Often such people are alternately
insulting and flattering, such as the person who posted this to a
Subversion mailing list:
Why is it that after almost 6 days there still aren't any
binaries posted for the windows platform?!? It's the same story every
time and it's pretty frustrating. Why aren't these things automated
so that they could be available immediately?? When you post an "RC"
build, I think the idea is that you want users to test the build, but
yet you don't provide any way of doing so. Why even have a soak
period if you provide no means of testing??
Initial response to this rather inflammatory post was
surprisingly restrained: people pointed out that the project had a
published policy of not providing official binaries, and said, with
varying degrees of annoyance, that he ought to volunteer to produce
them himself if they were so important to him. Believe it or not, his
next post started with these lines:
First of all, let me say that I think Subversion is awesome and
I really appreciate the efforts of everyone involved. [...]
...and then he went on to berate the project
again for not providing binaries, while
still not volunteering to do anything about it. After that, about
50 people just jumped all over him, and I can't say I really
minded. The "zero-tolerance" policy toward rudeness advocated in
in
applies to people with
whom the project has (or would like to have) a sustained interaction.
But when someone makes it clear from the start that he is going to
be a fountain of bile, there is no point making him feel welcome.
Such situations are fortunately quite rare, and they are
noticeably rarer in projects that make an effort to engage users
constructively and courteously from their very first
interaction.
Meeting In Person (Conferences, Hackfests, Code-a-Thons, Code Sprints, Retreats)
24 March 2013: If you're reading this note, then
you've encountered this section while it's undergoing substantial
revision; see producingoss.com/v2.html for details.
poss2 tbd
Some examples to use: Ubuntu community sprints, Adam
Hyde's flossmanuals doc sprints, and the Danese/Noel-style public
hackathons. Distinguish between purely dev events and
dev+user+funder+enterprise events — all are
useful, but don't confuse audiences.
Share Management Tasks as Well as Technical Tasks
Share the management burden as well as the technical burden of
running the project. As a project becomes more complex, more and more
of the work is about managing people and information flow. There is
no reason not to share that burden, and sharing it does not
necessarily require a top-down hierarchy either—what happens in
practice tends to be more of a peer-to-peer network topology than a
military-style command structure.
Sometimes management roles are formalized, and sometimes they
happen spontaneously. In the Subversion project, we have a patch
manager, a translation manager, documentation managers, issue managers
(albeit unofficial), and a release manager. Some of these roles we
made a conscious decision to initiate, others just happened by
themselves; as the project grows, I expect more roles to be added.
Below we'll examine these roles, and a couple of others, in detail
(except for release manager, which was already covered in
and
earlier
in this chapter).
As you read the role descriptions, notice that none of them
requires exclusive control over the domain in question. The issue
manager does not prevent other people from making changes in the
tickets database, the FAQ manager does not insist on being the only
person to edit the FAQ, and so on. These roles are all about
responsibility without monopoly. An important part of each domain
manager's job is to notice when other people are working in that domain,
and train them to do the things the way the manager does, so that the
multiple efforts reinforce rather than conflict. Domain managers
should also document the processes by which they do their work, so
that when one leaves, someone else can pick up the slack right
away.
Sometimes there is a conflict: two or more people want the same
role. There is no one right way to handle this. You could suggest
that each volunteer post a proposal (an "application") and have all
the committers vote on which is best. But this is cumbersome and
potentially awkward. I find that a better technique is just to ask the
multiple candidates to settle it among themselves. They usually will,
and will be more satisfied with the result than if a decision had been
imposed on them from the outside.
Patch Manager
In a free software project that receives a lot of patches,
keeping track of which patches have arrived and what has been decided
about them can be a nightmare, especially if done in a decentralized
way. Most patches arrive as posts to the project's development
mailing list (though some may appear first in the ticket tracker, or on
external web sites), and there are a number of different routes a
patch can take after arrival.
Sometimes someone reviews the patch, finds problems, and bounces
it back to the original author for cleanup. This usually leads to an
iterative process—all visible on the mailing list—in which
the original author posts revised versions of the patch until the
reviewer has nothing more to criticize. It is not always easy to tell
when this process is done: if the reviewer commits the patch, then
clearly the cycle is complete. But if she does not, it might be
because she simply didn't have time, or doesn't have commit access
herself and couldn't rope any of the other developers into doing
it.
Another frequent response to a patch is a freewheeling
discussion, not necessarily about the patch itself, but about whether
the concept behind the patch is good. For example, the patch may fix
a bug, but the project prefers to fix that bug in another way, as part
of solving a more general class of problems. Often this is not known
in advance, and it is the patch that stimulates the discovery.
Occasionally, a posted patch is met with utter silence. Usually
this is due to no developer having time at that
moment to review the patch, so each hopes that someone else
will do it. Since there's no particular limit to how long each person
waits for someone else to pick up the ball, and meanwhile other
priorities are always coming up, it's very easy for a patch to slip
through the cracks without any single person intending for that to
happen. The project might miss out on a useful patch this way, and
there are other harmful side effects as well: it is discouraging to
the author, who invested work in the patch, and it makes the project
as a whole look a bit out of touch, especially to others considering
writing patches.
The patch manager's job is to make sure that patches don't "slip
through the cracks." This is done by following every patch through to
some sort of stable state. The patch manager watches every mailing
list thread that results from a patch posting. If it ends in a commit
of the patch, he does nothing. If it goes into a review/revise
iteration, ending with a final version of the patch but no commit, he
files a ticket pointing to the final version, and to the mailing list
thread around it, so that there is a permanent record for developers
to follow up on later. If the patch addresses an existing ticket, he
annotates that ticket with the relevant information, instead of opening
a new ticket.
When a patch gets no reaction at all, the patch manager waits a
few days, then follows up asking if anyone is going to review it.
This usually gets a reaction: a developer may explain that she doesn't
think the patch should be applied, and give the reasons why, or she may
review it, in which case one of the previously described paths is
taken. If there is still no response, the patch manager may or may
not file a ticket for the patch, at his discretion, but at
least the original submitter got some
reaction.
Having a patch manager has saved the Subversion development team
a lot of time and mental energy. Without a designated person to take
responsibility, every developer would constantly have to worry "If I
don't have time to respond to this patch right now, can I count on
someone else doing it? Should I try to keep an eye on it? But if
other people are also keeping an eye on it, for the same reasons, then
we'd have needlessly duplicated effort." The patch manager removes
the second-guessing from the situation. Each developer can make the
decision that is right for her at the moment she first sees the patch.
If she wants to follow up with a review, she can do that—the
patch manager will adjust his behavior accordingly. If she wants to
ignore the patch completely, that's fine too; the patch manager will
make sure it isn't forgotten.
Because this system works only if people can depend on the patch
manager being there without fail, the role should be held formally.
In Subversion, we advertised for it on the development and users
mailing lists, got several volunteers, and took the first one who
replied. When that person had to step down (see
later in
this chapter), we did the same thing again.
We've never tried having multiple people share the role, because of
the communications overhead that would be required between them; but
perhaps at very high volumes of patch submission, a multiheaded patch
manager might make sense.
Translation Manager
In software projects, "translation" can refer to two very
different things. It can mean translating the software's
documentation into other languages, or it can mean translating the
software itself—that is, having the program display errors and
help messages in the user's preferred language. Both are complex
tasks, but once the right infrastructure is in place, they are largely
separable from other development. Because the tasks are similar in
some ways, it may make sense (depending on your project) to have a
single translation manager handle both, or it may be better to have
two different managers.
In the Subversion project, we have one translation manager
handle both. He does not actually write the translations himself, of
course—he may help out on one or two, but as of this writing, he
would need to speak ten languages (twelve counting dialects) in order
to work on all of them! Instead, he manages teams of volunteer
translators: he helps them coordinate among each other, and he
coordinates between the teams and the rest of the project.
Part of the reason the translation manager is necessary is that
translators are a different demographic from developers. They
sometimes have little or no experience working in a version control
repository, or indeed with working as part of a distributed volunteer
team at all. But in other respects they are often the best kind of
volunteer: people with specific domain knowledge who saw a need and
chose to get involved. They are usually willing to learn, and
enthusiastic to get to work. All they need is someone to tell them
how. The translation manager makes sure that the translations happen
in a way that does not interfere unnecessarily with regular
development. He also serves as a sort of representative of the
translators as a unified body, whenever the developers must be
informed of technical changes required to support the translation
effort.
Thus, the position's most important skills are diplomatic, not
technical. For example, in Subversion we have a policy that all
translations should have at least two people working on them, because
otherwise there is no way for the text to be reviewed. When a new
volunteer shows up offering to translate Subversion to, say, Malagasy,
the translation manager has to either hook him up with someone who
posted six months ago expressing interest in doing a Malagasy
translation, or else politely ask the volunteer to go
find another Malagasy translator to work with as
a partner. Once enough people are available, the manager sets them up
with the proper kind of commit access, informs them of the project's
conventions (such as how to write log messages), and then keeps an eye
out to make sure they adhere to those conventions.
Conversations between the translation manager and the
developers, or between the translation manager and translation teams,
are usually held in the project's original language—that is, the
language from which all the translations are being made. For most
free software projects, this is English, but it doesn't matter what it
is as long as the project agrees on it. (English is probably best for
projects that want to attract a broad international development
community, though.)
Conversations within a particular
translation team usually happen in their shared language, however, and
one of the other tasks of the translation manager is to set up a
dedicated mailing list for each team. That way the translators can
discuss their work freely, without distracting people on the project's
main lists, most of whom would not be able to understand the
translation language anyway.
Internationalization Versus Localization
Internationalization
(I18N) and localization
(L10N) both refer to the process of adapting
a program to work in linguistic and cultural environments other than
the one for which it was originally written. The terms are often
treated as interchangeable, but in fact they are not quite the same
thing. As en.wikipedia.org/wiki/G11n writes:
The distinction between them is subtle but important:
Internationalization is the adaptation of products
for potential use virtually everywhere, while
localization is the addition of special features for use in
a specific locale.
For example, changing your software to losslessly handle
Unicode (en.wikipedia.org/wiki/Unicode) text
encodings is an internationalization move, since it's not about a
particular language, but rather about accepting text from any of a
number of languages. On the other hand, making your software print
all error messages in Slovenian, when it detects that it is running
in a Slovenian environment, is a localization move.
Thus, the translation manager's task is principally about
localization, not internationalization.
Documentation Manager
Keeping software documentation up-to-date is a never-ending
task. Every new feature or enhancement that goes into the code has
the potential to cause a change in the documentation. Also, once the
project's documentation reaches a certain level of completeness, you
will find that a lot of the patches people send in are for the
documentation, not for the code. This is because there are many more
people competent to fix bugs in prose than in code: all users are
readers, but only a few are programmers.
Documentation patches are usually much easier to review and
apply than code patches. There is little or no testing to be done,
and the quality of the change can be evaluated quickly just by review.
Since the quantity is high, but the review burden fairly low, the
ratio of administrative overhead to productive work is greater for
documentation patches than for code patches. Furthermore, most of the
patches will probably need some sort of adjustment, in order to
maintain a consistent authorial voice in the documentation. In many
cases, patches will overlap with or affect other patches, and need to
be adjusted with respect to each other before being committed.
Given the exigencies of handling documentation patches, and the
fact that the code base needs to be constantly monitored so the
documentation can be kept up-to-date, it makes sense to have one
person, or a small team, dedicated to the task. They can keep a
record of exactly where and how the documentation lags behind the
software, and they can have practiced procedures for handling large
quantities of patches in an integrated way.
Of course, this does not preclude other people in the project
from applying documentation patches on the fly, especially small ones,
as time permits. And the same patch manager (see
earlier
in this chapter) can track both code and
documentation patches, filing them wherever the development and
documentation teams want them, respectively. (If the total quantity of
patches ever exceeds one human's capacity to track, though, switching
to separate patch managers for code and documentation is probably a
good first step.) The point of a documentation team is to have people
who think of themselves as responsible for keeping the documentation
organized, up-to-date, and consistent with itself. In practice, this
means knowing the documentation intimately, watching the code base,
watching the changes
others commit to the documentation, watching for
incoming documentation patches, and using all these information
sources to do whatever is necessary to keep the documentation
healthy.
Issue Manager
The number of tickets in a project's bug tracker grows in
proportion to the number of people using the software. Therefore,
even as you fix bugs and ship an increasingly robust program, you
should still expect the number of open tickets to grow essentially
without bound. The frequency of duplicate tickets will also increase,
as will the frequency of incomplete or poorly described tickets.
An issue managerIn the
nomenclature I've been using elsewhere in this book, this position
might be called "ticket manager", but in practice no project calls it
that, and most call it "issue manager", so that's what we'll use here
too. helps alleviate these problems by
watching what goes into the database, and periodically sweeping
through it looking for specific problems. Their most common action is
probably to fix up incoming tickets, either because the reporter
didn't set some of the form fields correctly, or because the ticket is
a duplicate of one already in the database. Obviously, the more
familiar an issue manager is with the project's bug database, the
more efficiently she will be able to detect duplicate
tickets—this is one of the main advantages of having a few
people specialize in the bug database, instead of everyone trying to
do it ad hoc. When the group tries to
do it in a decentralized manner, no single individual acquires a deep
expertise in the content of the database.
issue managers can also help map between tickets and individual
developers. When there are a lot of bug reports coming in, not every
developer may read the ticket notification mailing list with equal
attention. However, if someone who knows the development team is
keeping an eye on all incoming tickets, then she can discreetly direct
certain developers' attention to specific bugs when appropriate. Of
course, this has to be done with a sensitivity to everything else
going on in development, and to the recipient's desires and
temperament. Therefore, it is often best for issue managers to be
developers themselves.
Depending on how your project uses the ticket tracker, issue
managers can also shape the database to reflect the project's
priorities. For example, in Subversion we schedule tickets into
specific future releases, so that when someone asks "When will bug X
be fixed?" we can say "Two releases from now," even if we can't give
an exact date. The releases are represented in the ticket tracker as
target milestones, a field available in
IssueZilla.IssueZilla is the ticket tracker we use; it
is a descendant of BugZilla. As a rule, every
Subversion release has one major new feature and a list of specific
bug fixes. We assign the appropriate target milestone to all the
tickets planned for that release (including the new feature—it
gets a ticket too), so that people can view the bug database through
the lens of release scheduling. These targets rarely remain static,
however. As new bugs come in, priorities sometimes get shifted
around, and tickets must be moved from one milestone to another so that
each release remains manageable. This, again, is best done by people
who have an overall sense of what's in the database, and how various
tickets relate to each other.
Another thing issue managers do is notice when tickets become
obsolete. Sometimes a bug is fixed accidentally as part of an
unrelated change to the software, or sometimes the project changes its
mind about whether a certain behavior is buggy. Finding obsoleted
tickets is not easy: the only way to do it systematically is by making
a sweep over all the tickets in the database. Full sweeps become less
and less feasible over time, however, as the number of tickets grows.
After a certain point, the only way to keep the database sane is to use a
divide-and-conquer approach: categorize tickets immediately on arrival
and direct them to the appropriate developer's or team's attention.
The recipient then takes charge of the ticket for the rest of its
lifetime, shepherding it to resolution or oblivion as necessary. When
the database is that large, the issue manager becomes more of an
overall coordinator, spending less time looking at each ticket herself
and more time getting it into the right person's hands.
FAQ Manager
FAQ maintenance is a surprisingly difficult problem. Unlike
most other documents in a project, whose content is planned out in
advance by the authors, a FAQ is a wholly reactive document (see
in
). No matter how big it gets, you
still never know what the next addition will be. And because it is
always added to piecemeal, it is very easy for the document as a whole
to become incoherent and disorganized, and even to contain duplicate
or semi-duplicate entries. Even when it does not have any obvious
problems like that, there are often unnoticed interdependencies
between items—links that should be made but aren't—because
the related items were added a year apart.
The role of a FAQ manager is twofold. First, she maintains the
overall quality of the FAQ by staying familiar with at least the
topics of all the questions in it, so that when people add new items
that are duplicates of, or related to, existing items, the appropriate
adjustments can be made. Second, she watches the project mailing
lists and other forums for recurring problems or questions, and to
write new FAQ entries based on this input. This latter task can be
quite complex: one must be able to follow a thread, recognize the core
questions raised in it, post a proposed FAQ entry, incorporate
comments from others (since it's impossible for the FAQ manager to be
an expert in every topic covered by the FAQ), and sense when the
process is finished so the item can at last be added.
The FAQ manager usually also becomes the default expert in FAQ
formatting. There are a lot of little details involved in keeping a
FAQ in shape (see
in
); when random
people edit the FAQ, they will sometimes forget some of these details.
That's okay, as long as the FAQ manager is there to clean up after
them.
Various free software is available to help with the process of
FAQ maintenance. It's fine to use it, as long as it doesn't
compromise the quality of the FAQ, but beware of over-automation.
Some projects try to fully automate the process of FAQ maintenance,
allowing everyone to contribute and edit FAQ items in a manner similar
to a wiki (see
in ). I've
seen this happen particularly with Faq-O-Matic
(faqomatic.sourceforge.net), though it may be
that the cases I saw were simply abuses that went beyond what
Faq-O-Matic was originally intended for. In any case, while complete
decentralization of FAQ maintenance does reduce the workload for the
project, it also results in a poorer FAQ. There's no one person with
a broad view of the entire FAQ, no one to notice when certain items
need updating or become obsolete entirely, and no one keeping watch for
interdependencies between items. The result is a FAQ that often fails
to provide users what they were looking for, and in the worst cases
misleads them. Use whatever tools you need to maintain your
project's FAQ, but never let the convenience of the tools seduce you
into compromising the quality of the FAQ.
See Sean Michael Kerner's article, The FAQs on
FAQs, at
osdir.com/Article1722.phtml, for descriptions
and evaluations of open source FAQ maintenance tools.
Transiciones
De vez en cuando, un voluntario en un puesto de responsabilidad
en curso (por ejemplo, gestor de parches, gestor de traducciones, etc)
será incapaz de realizar las tareas del cargo. Puede ser debido a que
el trabajo resultó ser más de lo que esperaba, o puede ser debido a
factores completamente externos: el matrimonio, un nuevo bebé, un
nuevo empleador, o lo que sea.
Cuando un voluntario se satura de esa manera, que por lo general
no lo nota enseguida. Sucede poco a poco, y no hay punto en el que
conscientemente se de cuenta que ya no puede cumplir con los deberes
de la función. En cambio, el resto del proyecto simplemente no oye
mucho de él por un tiempo. Luego habrá de repente una ráfaga de
actividad, ya que se siente culpable por dejar de lado el proyecto
durante tanto tiempo y aparta una noche para ponerse al día. Luego no
habrá noticias de él por un tiempo más largo, y entonces podría o no
haber otra ráfaga. Pero rara vez hay una solicitud formal de renuncia.
El voluntario estaba haciendo el trabajo en su tiempo libre, por lo
que renunciar significaría reconocer abiertamente a sí mismo que su
tiempo libre se reduce de forma permanente. Las personas a menudo son
reacias a hacerlo.
Por lo tanto, depende de ti y de los demás en el proyecto el
darse cuenta de lo que está pasando—o más bien, lo que no está
pasando— y preguntar al voluntario qué está sucediendo. La
investigación debe ser amable y 100% libre de culpa. Su propósito es
encontrar un poco de información, no hacer que la persona se sienta
mal. En general, la investigación debe ser visible para el resto del
proyecto, pero si sabes de alguna razón especial por la que una
investigación privada sería mejor, eso también está bien. La razón
principal para hacerlo públicamente es para que si el voluntario
responde diciendo que no va a ser capaz de hacer más el trabajo, hay
un marco establecido para tu próximo mensaje
público: una solicitud de nuevo voluntario para cumplir esa
función.
A veces, un voluntario no es capaz de hacer el trabajo que ha
tomado, pero bien desconocen o no están dispuestos a admitir este
hecho. Por supuesto, cualquier persona puede tener problemas al
principio, especialmente si la responsabilidad es compleja. Sin
embargo, si alguien no está funcionando en la tarea que está llevando
adelante, incluso después de que todo el mundo ha dado toda la ayuda
y sugerencias que pueden, entonces la única solución es que hacerlo
a un lado y dejar que alguien nuevo haga el intento. Y si la persona
no lo ve por sí mismo, habrá que decírselo. Hay, básicamente, sólo una
manera de manejar esto, creo, pero es un proceso de varios pasos y
cada paso es importante.
En primer lugar, asegúrate de que no estás loco. En privado
habla con otros en el proyecto para ver si están de acuerdo en que el
problema es tan grave como piensas que es. Incluso si ya estás seguro,
esto tiene el propósito de dejar que los demás sepan que estás
pensando en pedir a la persona que se haga a un lado. Por lo general,
nadie se opondrá a esto—simplemente estarán felices de que tú
estás tomando esta difícil tarea, ¡así que no tienen que hacerla
ellos!
A continuación, en privado contacta con el
voluntario en cuestión y dile, amable pero directamente, sobre los
problemas que ves. Sé específico, facilitando tantos ejemplos como sea
posible. Asegúrate de señalar cómo la gente había tratado de ayudar,
pero que los problemas persistieron sin mejorar. Debes esperar que
este correo te tome mucho tiempo para escribirlo, pero con este tipo
de mensaje, si no respaldas de lo que estás diciendo, no debes decir
nada en absoluto. Di que deseas encontrar un nuevo voluntario
para desempeñar ese rol, pero también señala que hay muchas otras
maneras de contribuir al proyecto. En esta etapa, no digas que has
hablado con otros acerca de él; a nadie le gusta que le digan que la
gente estaba conspirando a sus espaldas.
Hay algunas maneras diferentes en que las cosas pueden salir
después de eso. La reacción más probable es que él estará de acuerdo
con usted, o en todo caso no querrá discutir, y estará dispuesto a
renunciar. En ese caso, sugiere que el mismo haga el anuncio, y
luego puedes seguir con un mensaje buscando un reemplazo.
O, el podría aceptar que ha habido problemas, pero pide un poco
más de tiempo (o una oportunidad más, en el caso de los roles de
tareas discretas como gestor de liberaciones). Cómo reaccionar a eso
es una cuestión de criterio, pero hagas lo que hagas, no lo aceptes
sólo porque sientes que no puedes rechazar una petición tan razonable.
Eso sería prolongar la agonía, no disminuirla. A menudo hay una muy
buena razón para rechazar la petición, es decir, que ya ha habido un
montón de posibilidades, y así es como las cosas llegaron a donde
están ahora. Así es como yo lo puse en un correo electrónico a
alguien que estaba ocupando el rol gestor liberaciones, pero realmente
no era adecuado para ello:
> Si quieres reemplazarme con alguien más, pasaré gentilmente el
> rol a quien venga a continuación. Tengo una petición, que espero
> que no sea poco razonable. Me gustaría intentar una liberación
> más en un esfuerzo por demostrar lo que valgo.
Entiendo perfectamente tu deseo (¡yo he estado allí!), Pero en este
caso, no deberíamos hacer la cuestión del "un intento más".
Esta no es la primera o la segunda liberación, esta es la sexta o
séptima... Y para todas ellas, sé que has estado insatisfecho con los
resultados también (porque lo que hemos hablado antes). Así que ya
hemos efectivamente recorrido la ruta del "un intento más".
Eventualmente, uno de los intentos tiene que ser el último... Creo que
[esta liberación anterior] debe ser eso.
En el peor de los casos, el voluntario puede estar en desacuerdo
absoluto. Entonces tienes que aceptar que las cosas van a ser
incómodas y difíciles de todos modos. Ahora es el momento de decir que
has hablado con otras personas sobre él (pero aún no se dice con quién
hasta que tengas permiso, ya que esas conversaciones eran
confidenciales), y que no crees que sea bueno para el proyecto que
continúen las cosas como están. Se insistente, pero nunca
amenazante. Ten en cuenta que con la mayoría de las funciones, la
transición realmente sucede en el momento que alguien nuevo empieza a
hacer el trabajo, no el momento en que la persona
anterior deja hacerlo. Por ejemplo, si la controversia es sobre el rol
de, por ejemplo, gestor de incidencias, en cualquier momento tú y
otras personas influyentes en el proyecto pueden solicitar un nuevo
gestor de incidencias. En realidad no es necesario que la persona que
lo estaba haciendo antes deje de hacerlo, siempre y cuando no sabotee
(deliberadamente o no) los esfuerzos del nuevo voluntario.
Lo que nos lleva a un pensamiento tentador: en lugar de
pedir a la persona que renuncie, ¿por qué no enmarcarlo como un
asunto de conseguirle un poco de ayuda? ¿Por qué no tener dos gestores
de incidencias o gestores de parches, o cualquiera que sea el
rol?
Aunque esto puede sonar bien en teoría, por lo general no es una
buena idea. Lo que hace que los roles de coordinación
funcionen—lo que los hace útiles, de hecho—es su
centralización. Esas cosas que se pueden hacer de manera
descentralizada por lo general ya se están haciendo de esa manera.
Tener dos personas ocupando una función coordinadora introduce una
sobrecarga de comunicaciones entre esas dos personas, así como el
potencial de desplazamiento resbaladizo de la responsabilidad ("¡Pensé
que tu traías el botiquín de primeros auxilios!" "¿Yo? No, ¡yo pensé
que tu traías el botiquín de primeros
auxilios!"). Por supuesto, hay excepciones. A veces dos personas
trabajan muy bien juntos, o la naturaleza de la función es tal que se
puede propagar fácilmente a través de múltiples personas. Pero estos
no son propensos a ser de mucha utilidad cuando ves a alguien
golpeándose contra un rol para el que no es adecuado. Si él hubiera
apreciado el problema en primer lugar, habría buscado esa ayuda antes
de ahora. En cualquier caso, sería una falta de respeto dejar perder
el tiempo a alguien haciendo un trabajo que nadie va a prestar
atención.
El factor más importante en pedir a alguien que dimita es la
privacidad: darle la posibilidad de tomar una decisión sin sentir que
otros están mirando y esperando. Una vez cometí el error—un
error evidente, en retrospectiva—de enviar un correo a las tres
partes a la vez con el fin de pedirle al coordinador de liberaciones
de Subversion hacerse a un lado en favor de otros dos voluntarios. Yo
ya había hablado con las dos nuevas personas en privado, y sabía que
ellos estaban dispuestos a asumir la responsabilidad. Así que pensé,
ingenua y algo insensiblemente, que ahorraría un poco de tiempo y la
molestia de enviar un correo electrónico a todos ellos para iniciar la
transición. Supuse que el coordinador de liberaciones actual ya era
plenamente consciente de los problemas y vería inmediatamente la
sensatez de mi punto.
Yo estaba equivocado. El coordinador liberaciones actual estaba
muy ofendido, y con razón. Una cosa es que se le pida retirarse del
trabajo; otra cosa es que se le pida frente a las
personas que van a reemplazarlo. Una vez que tuve en mente por qué se
sintió ofendido, me disculpé. Con el tiempo se hizo un a un lado
gentilmente, y sigue participando en el proyecto hoy en día. Pero
sus sentimientos estaban heridos, y no hace falta decir que esto no
era tampoco el comienzo más propicio para los nuevos
voluntarios.
Committers
poss todo: 2 February 2014: If you're reading this note, then
you've encountered this section while it's undergoing substantial
revision; see producingoss.com/v2.html for details. The particular change
that needs to happen here is that this section needs to make a
terminology point: that "committer" in this context really means
"maintainer". That is, the footnote below probably needs to be
brought out into its own paragraph, and early on. This is because the
term "commit" is used slightly differently in decentralized version
control systems than in centralized ones (and it certainly won't work
to call that class of people "pushers", ahem). Interestingly, the
term "committer" is still widely used even in decentralized systems to
mean "someone who can put changes in the socially-accepted master
repository".
As the only formally distinct class of people found in all open
source projects, committers deserve special attention here.
Committers are an unavoidable concession to discrimination in a system
which is otherwise as non-discriminatory as possible. But
"discrimination" is not meant as a pejorative here. The function
committers perform is utterly necessary, and I do not think a project
could succeed without it. Quality control requires, well, control.
There are always many people who feel competent to make changes to a
program, and some smaller number who actually are. The project cannot
rely on people's own judgement; it must impose standards and grant
commit access only to those who meet themNote that the
commit access means something a bit different in decentralized version
control systems, where anyone can set up a repository that is linked
into the project, and give themselves commit access to that
repository. Nevertheless, the concept of commit
access still applies: "commit access" is shorthand for "the
right to make changes to the code that will ship in the group's next
release of the software." In centralized version control systems,
this means having direct commit access; in decentralized ones, it
means having one's changes pulled into the main distribution by
default. It is the same idea either way; the mechanics by which it is
realized are not terribly important.. On the other
hand, having people who can commit changes directly working
side-by-side with people who cannot sets up an obvious power dynamic.
That dynamic must be managed so that it does not harm the
project.
In
in , we already
discussed the mechanics of considering new committers. Here we will
look at the standards by which potential new committers should be
judged, and how this process should be presented to the larger
community.
Choosing Committers
In the Subversion project, we choose committers primarily on the
Hippocratic Principle: first, do no harm. Our
main criterion is not technical skill or even knowledge of the code,
but merely that the committer show good judgement. Judgement can mean
simply knowing what not to take on. A person might post only small
patches, fixing fairly simple problems in the code; but if the patches
apply cleanly, do not contain bugs, and are mostly in accord with the
project's log message and coding conventions, and there are enough
patches to show a clear pattern, then an existing committer will
usually propose that person for commit access. If at least three
people say yes, and no one objects, then the offer is made. True, we
might have no evidence that the person is able to solve complex
problems in all areas of the code base, but that does not matter: the
person has made it clear that he is capable of at least judging
his own abilities. Technical skills can be learned (and taught),
but judgement, for the most part, cannot. Therefore, it is the one
thing you want to make sure a person has before you give him commit
access.
When a new committer proposal does provoke a discussion, it is
usually not about technical ability, but rather about the person's
behavior on the mailing lists or in IRC. Sometimes someone shows
technical skill and an ability to work within the project's formal
guidelines, yet is also consistently belligerent or uncooperative in
public forums. That's a serious concern; if the person doesn't
seem to shape up over time, even in response to hints, then we won't
add him as a committer no matter how skilled he is. In a
volunteer group, social skills, or the ability to "play well in the
sandbox", are as important as raw technical ability. Because
everything is under version control, the penalty for adding a
committer you shouldn't have is not so much the problems it could
cause in the code (review would spot those quickly anyway), but that
it might eventually force the project to revoke the person's commit
access—an action that is never pleasant and can sometimes be
confrontational.
Many projects insist that the potential committer demonstrate a
certain level of technical expertise and persistence, by submitting
some number of nontrivial patches—that is, not only do these
projects want to know that the person will do no harm, they want to
know that she is likely to do good across the code base. This is
fine, but be careful that it doesn't start to turn committership into
a matter of membership in an exclusive club. The question to keep in
everyone's mind should be "What will bring the best results for the
code?" not "Will we devalue the social status associated with
committership by admitting this person?" The point of commit access
is not to reinforce people's self-worth, it's to allow good changes to
enter the code with a minimum of fuss. If you have 100
committers, 10 of whom make large changes on a regular basis, and the
other 90 of whom just fix typos and small bugs a few times a year,
that's still better than having only the 10.
Revoking Commit Access
The first thing to be said about revoking commit access is: try
not to be in that situation in the first place. Depending on whose
access is being revoked, and why, the discussions around such an
action can be very divisive. Even when not divisive, they will be a
time-consuming distraction from productive work.
However, if you must do it, the discussion should be had
privately among the same people who would be in a position to vote for
granting that person whatever flavor of commit
access they currently have. The person herself should not be
included. This contradicts the usual injunction against secrecy, but
in this case it's necessary. First, no one would be able to speak
freely otherwise. Second, if the motion fails, you don't necessarily
want the person to know it was ever considered, because that could
open up questions ("Who was on my side? Who was against me?") that
lead to the worst sort of factionalism. In certain rare
circumstances, the group may want someone to know that revocation of
commit access is or was being considered, as a warning, but this
openness should be a decision the group makes. No one should ever, on
her own initiative, reveal information from a discussion and ballot
that others assumed were secret.
Once someone's access is revoked, that fact is unavoidably
public (see
later in this chapter), so try to be as tactful as you can in
how it is presented to the outside world.
Partial Commit Access
Some projects offer gradations of commit access. For example,
there might be contributors whose commit access gives them free rein
in the documentation, but who do not commit to the code itself.
Common areas for partial commit access include documentation,
translations, binding code to other programming languages,
specification files for packaging (e.g., RedHat RPM spec files,
etc.), and other places where a mistake will not result in a problem for
the core project.
Since commit access is not only about committing, but about
being part of an electorate (see
in
),
the question naturally arises: what can the partial committers vote
on? There is no one right answer; it depends on what sorts of partial
commit domains your project has. In Subversion we've kept things
fairly simple: a partial committer can vote on matters confined
exclusively to that committer's domain, and not on anything else.
Importantly, we do have a mechanism for casting advisory votes
(essentially, the committer writes "+0" or "+1 (non-binding)"
instead of just "+1" on the ballot). There's no reason to silence
people entirely just because their vote isn't formally binding.
Full committers can vote on anything, just as they can commit
anywhere, and only full committers vote on adding new committers of
any kind. In practice, though, the ability to add new partial
committers is usually delegated: any full committer can "sponsor" a
new partial committer, and partial committers in a domain can often
essentially choose new committers for that same domain (this is
especially helpful in making translation work run smoothly).
Your project may need a slightly different arrangement,
depending on the nature of the work, but the same general principles
apply to all projects. Each committer should be able to vote on
matters that fall within the scope of her commit access, and not on
matters outside that, and votes on procedural questions should default
to the full committers, unless there's some reason (as decided by the
full committers) to widen the electorate.
Regarding enforcement of partial commit access: it's often
best not to have the version control system
enforce partial commit domains, even if it can. See
in
for the
reasons why.
Dormant Committers
Some projects automatically remove people's commit access if
they go a certain amount of time (say, a year) without committing
anything. I think this is usually unhelpful and even
counterproductive, for two reasons.
First, it may tempt some people into committing acceptable but
unnecessary changes, just to prevent their commit access from
expiring. Second, it doesn't really serve any purpose. If the
main criterion for granting commit access is good judgement, then why
assume someone's judgement would deteriorate just because he's away
from the project for a while? Even if he completely vanishes for
years, not looking at the code or following development discussions,
when he reappears he'll know how out of touch
he is, and act accordingly. You trusted his judgement before, so
why not trust it always? If high school diplomas do not expire, then
commit access certainly shouldn't.
Sometimes a committer may ask to be removed, or to be explicitly
marked as dormant in the list of committers (see
below for more about that list). In these cases, the project
should accede to the person's wishes, of course.
Avoid Mystery
Although the discussions around adding any particular new
committer must be confidential, the rules and procedures themselves
need not be secret. In fact, it's best to publish them, so people
realize that the committers are not some mysterious Star Chamber,
closed off to mere mortals, but that anyone can join simply by posting
good patches and knowing how to handle herself in the community.
In the Subversion project, we put this information right in the
developer guidelines document, since the people most likely to be
interested in how commit access is granted are those thinking of
contributing code to the project.
In addition to publishing the procedures, publish the
actual list of committers. The traditional place
for this is a file called MAINTAINERS
or COMMITTERS in the top level of the project's
source code tree. It should list all the full committers first,
followed by the various partial commit domains and the members of each
domain. Each person should be listed by name and email address,
though the address can be encoded to prevent spam (see
in
) if the
person prefers that.
Since the distinction between full commit and partial commit
access is obvious and well defined, it is proper for the list to make
that distinction too. Beyond that, the list should not try to
indicate the informal distinctions that inevitably arise in a project,
such as who is particularly influential and how. It is a public
record, not an acknowledgments file. List committers either in
alphabetical order, or in the order in which they arrived.
Credit
Credit is the primary currency of the free software world.
Whatever people may say about their motivations for participating in a
project, I don't know any developers who would be happy doing all
their work anonymously, or under someone else's name. There are
tangible reasons for this: one's reputation in a project roughly
governs how much influence one has, and participation in an open
source project can also indirectly have monetary value, because
some employers now look for it on resumés. There are also
intangible reasons, perhaps even more powerful: people simply want to
be appreciated, and instinctively look for signs that their work was
recognized by others. The promise of credit is therefore one of best
motivators the project has. When small contributions are
acknowledged, people come back to do more.
One of the most important features of collaborative development
software (see ) is that
it keeps accurate records of who did what, when. Wherever possible,
use these existing mechanisms to make sure that credit is distributed
accurately, and be specific about the nature of the contribution.
Don't just write "Thanks to J. Random <jrandom@example.com>" if
instead you can write "Thanks to J. Random <jrandom@example.com>
for the bug report and reproduction recipe" in a log message.
In Subversion, we have an informal but consistent policy of
crediting the reporter of a bug in either the ticket filed, if there is
one, or the log message of the commit that fixes the bug, if not. A
quick survey of Subversion commit logs up to commit number 14525 shows
that about 10% of commits give credit to someone by name and email
address, usually the person who reported or analyzed the bug fixed by
that commit. Note that this person is different from the developer
who actually made the commit, whose name is already recorded
automatically by the version control system. Of the 80-odd full and
partial committers Subversion has today, 55 were credited in the
commit logs (usually multiple times) before they became committers
themselves. This does not, of course, prove that being credited was a
factor in their continued involvement, but it at least sets up an
atmosphere in which people know they can count on their contributions
being acknowledged.
It is important to distinguish between routine acknowledgment
and special thanks. When discussing a particular piece of code, or
some other contribution someone made, it is fine to acknowledge their
work. For example, saying "Daniel's recent changes to the delta code
mean we can now implement feature X" simultaneously helps people
identify which changes you're talking about and acknowledges Daniel's
work. On the other hand, posting solely to thank Daniel for the delta
code changes serves no immediate practical purpose. It doesn't add
any information, since the version control system and other mechanisms
have already recorded the fact that he made the changes. Thanking
everyone for everything would be distracting and ultimately
information-free, since thanks are effective largely by how much they
stand out from the default, background level of favorable comment
going on all the time. This does not mean, of course, that you should
never thank people. Just make sure to do it in ways that tend not to
lead to credit inflation. Following these guidelines will
help:
The more ephemeral the forum, the more free you
should feel to express thanks there. For example,
thanking someone for their bugfix in passing during an IRC
conversation is fine, as is an aside in an email devoted
mainly to other topics. But don't post an email solely to
thank someone, unless it's for a truly unusual feat.
Likewise, don't clutter the project's web pages with
expressions of gratitude. Once you start that, it'll
never be clear when or where to stop. And
never put thanks into comments in the
code; that would only be a distraction from the primary
purpose of comments, which is to help the reader
understand the code.
The less involved someone is in the project, the
more appropriate it is to thank her for something she
did. This may sound counterintuitive, but it fits with
the attitude that expressing thanks is something you do
when someone contributes even more than you thought she
would. Thus, to constantly thank regular contributors for
doing what they normally do would be to express a lower
expectation of them than they have of themselves. If
anything, you want to aim for the opposite effect!
There are occasional exceptions to this rule. It's
acceptable to thank someone for fulfilling his expected
role when that role involves temporary, intense efforts
from time to time. The canonical example is the release
manager, who goes into high gear around the time of each
release, but otherwise lies dormant (dormant as a release
manager, in any case—he may also be an active
developer, but that's a different matter).
As with criticism and crediting, gratitude should
be specific. Don't thank people just for being great,
even if they are. Thank them for something they did that
was out of the ordinary, and for bonus points, say
exactly why what they did was so great.
In general, there is always a tension between making sure that
people's individual contributions are recognized, and making sure the
project is a group effort rather than a collection of individual
glories. Just remain aware of this tension and try to err on the
side of group, and things won't get out of hand.
Forks
In
in , we saw how
the potential to fork has important effects on
how projects are governed. But what happens when a fork actually
occurs? How should you handle it, and what effects can you expect it
to have? Conversely, when should you initiate a
fork?
The answers depend on what kind of fork it is. Some forks are
due to amicable but irreconcilable disagreements about the direction
of the project; perhaps more are due to both technical disagreements
and interpersonal conflicts. Of course, it's not always possible to
tell the difference between the two, as technical arguments may
involve personal elements as well. What all forks have in common is
that one group of developers (or sometimes even just one developer)
has decided that the costs of working with some or all of the others
now outweigh the benefits.
Once a project forks, there is no definitive answer to the
question of which fork is the "true" or "original" project. People
will colloquially talk of fork F coming out of project P, as though P
is continuing unchanged down some natural path while F diverges into
new territory, but this is, in effect, a declaration of how that
particular observer feels about it. It is fundamentally a matter of
perception: when a large enough percentage of observers agree, the
assertion starts to become true. It is not the case that there is an
objective truth from the outset, one that we are only imperfectly able to
perceive at first. Rather, the perceptions are
the objective truth, since ultimately a project—or a
fork—is an entity that exists only in people's minds
anyway.
If those initiating the fork feel that they are
sprouting a new branch off the main project, the perception question
is resolved immediately and easily. Everyone, both developers and
users, will treat the fork as a new project, with a new name (perhaps
based on the old name, but easily distinguishable from it), a separate
web site, and a separate philosophy or goal. Things get messier,
however, when both sides feel they are the legitimate guardians of the
original project and therefore have the right to continue using the
original name. If there is some organization with trademark rights to
the name, or legal control over the domain or web pages, that usually
resolves the issue by fiat: that organization will decide who is the
project and who is the fork, because it holds all the cards in a
public relations war. Naturally, things rarely get that far: since
everyone already knows what the power dynamics are, they will avoid
fighting a battle whose outcome is known in advance, and just jump
straight to the end.
Fortunately, in most cases there is little doubt as to which is
the project and which is the fork, because a fork is, in essence, a vote
of confidence. If more than half of the developers are in favor of
whatever course the fork proposes to take, usually there is no need to
fork—the project can simply go that way itself, unless it is run
as a dictatorship with a particularly stubborn dictator. On the other
hand, if fewer than half of the developers are in favor, the fork is a
clearly minority rebellion, and both courtesy and common sense
indicate that it should think of itself as the divergent branch rather
than the main line.
Handling a Fork
If someone threatens a fork in your project, keep calm and
remember your long-term goals. The mere
existence of a fork isn't what hurts a project;
rather, it's the loss of developers and users. Your real aim,
therefore, is not to squelch the fork, but to minimize these harmful
effects. You may be mad, you may feel that the fork was unjust and
uncalled for, but expressing that publicly can only alienate undecided
developers. Instead, don't force people to make exclusive choices,
and be as cooperative as is practicable with the fork. To start with,
don't remove someone's commit access in your project just because he
decided to work on the fork. Work on the fork doesn't mean that
person has suddenly lost his competence to work on the original
project; committers before should remain committers afterward. Beyond
that, you should express your desire to remain as compatible as
possible with the fork, and say that you hope developers will port
changes between the two whenever appropriate. If you have
administrative access to the project's servers, publicly offer the
forkers infrastructure help at startup time. For example, offer them
a complete, deep-history copy of the version control repository, if
there's no other way for them to get it, so that they don't have to
start off without historical data (this may not be necessary depending
on the version control system). Ask them if there's anything else
they need, and provide it if you can. Bend over backward to show
that you are not standing in the way, and that you want the fork to
succeed or fail on its own merits and nothing else.
The reason to do all this—and do it publicly—is not
to actually help the fork, but to persuade developers that your side
is a safe bet, by appearing as non-vindictive as possible. In war it
sometimes makes sense (strategic sense, if not human sense) to force
people to choose sides, but in free software it almost never does. In
fact, after a fork some developers often openly work on both projects,
and do their best to keep the two compatible. These developers help
keep the lines of communication open after the fork. They allow your
project to benefit from interesting new features in the fork (yes, the
fork may have things you want), and also increase the chances of a
merger down the road.
Sometimes a fork becomes so successful that, even though it was
regarded even by its own instigators as a fork at the outset, it
becomes the version everybody prefers, and eventually supplants the
original by popular demand. A famous instance of this was the
GCC/EGCS fork. The GNU Compiler Collection
(GCC, formerly the GNU C
Compiler) is the most popular open source native-code
compiler, and also one of the
most portable compilers in the world. Due to disagreements between the GCC's
official maintainers and Cygnus Software,Now part of
RedHat (redhat.com). one
of GCC's most active developer groups, Cygnus created a fork of GCC
called EGCS. The fork was deliberately
non-adversarial: the EGCS developers did not, at any point, try to
portray their version of GCC as a new official version. Instead, they
concentrated on making EGCS as good as possible, incorporating patches
at a faster rate than the official GCC maintainers. EGCS gained in
popularity, and eventually some major operating system distributors
decided to package EGCS as their default compiler instead of GCC. At
this point, it became clear to the GCC maintainers that holding on to
the "GCC" name while everyone switched to the EGCS fork would burden
everyone with a needless name change, yet do nothing to prevent the
switchover. So GCC adopted the EGCS codebase, and there is once again
a single GCC, but greatly improved because of the fork.
This example shows why you cannot always regard a fork as an
unadulteratedly bad thing. A fork may be painful and unwelcome at the
time, but you cannot necessarily know whether it will succeed.
Therefore, you and the rest of the project should keep an eye on it,
and be prepared not only to absorb features and code where possible,
but in the most extreme case to even join the fork if it gains the
bulk of the project's mindshare. Of course, you will often be able to
predict a fork's likelihood of success by seeing who joins it. If the
fork is started by the project's biggest complainer and joined by a
handful of disgruntled developers who weren't behaving constructively
anyway, they've essentially solved a problem for you by forking, and
you probably don't need to worry about the fork taking momentum away
from the original project. But if you see influential and respected
developers supporting the fork, you should ask yourself why. Perhaps
the project was being overly restrictive, and the best solution is to
adopt into the mainline project some or all of the actions
contemplated by the fork—in essence, to avoid the fork by
becoming it.
Initiating a Fork
All the advice here assumes that you are forking as a last
resort. Exhaust all other possibilities before starting a fork.
Forking almost always means losing developers, with only an uncertain
promise of gaining new ones later. It also means starting out with
competition for users' attention: everyone who's about to download the
software has to ask themselves: "Hmm, do I want that one or the other
one?" Whichever one you are, the situation is messy, because a
question has been introduced that wasn't there before. Some people
maintain that forks are healthy for the software ecosystem as a whole,
by a standard natural selection argument: the fittest will survive,
which means that, in the end, everyone gets better software. This may
be true from the ecosystem's point of view, but it's not true from the
point of view of any individual project. Most forks do not succeed,
and most projects are not happy to be forked.
A corollary is that you should not use the threat of a fork as
an extremist debating technique—"Do things my way or I'll fork
the project!"—because everyone is aware that a fork that fails
to attract developers away from the original project is unlikely to
survive long. All observers—not just developers, but users and
operating system packagers too—will make their own judgement about
which side to choose. You should therefore appear extremely reluctant
to fork, so that if you finally do it, you can credibly claim it was
the only route left.
Do not neglect to take all factors into
account in evaluating the potential success of your fork. For
example, if many of the developers on a project have the same
employer, then even if they are disgruntled and privately in favor of
a fork, they are unlikely to say so out loud if they know that their
employer is against it. Many free software programmers like to think
that having a free license on the code means no one company can
dominate development. It is true that the license is, in an ultimate
sense, a guarantor of freedom—if others want badly enough to
fork the project, and have the resources to do so, they can. But in
practice, some projects' development teams are mostly funded by one
entity, and there is no point pretending that the entity's support
doesn't matter. If it is opposed to the fork, its developers are
unlikely to take part, even if they secretly want to.
If you still conclude that you must fork, line up support
privately first, then announce the fork in a non-hostile tone. Even
if you are angry at, or disappointed with, the current maintainers,
don't say that in the message. Just dispassionately state what led
you to the decision to fork, and that you mean no ill will toward the
project from which you're forking. Assuming that you do consider it a
fork (as opposed to an emergency preservation of the original
project), emphasize that you're forking the code and not the name, and
choose a name that does not conflict with the project's name. You can
use a name that contains or refers to the original name, as long as it
does not open the door to identity confusion. Of course it's fine to
explain prominently on the fork's home page that it descends from the
original program, and even that it hopes to supplant it. Just don't
make users' lives harder by forcing them to untangle an identity
dispute.
Finally, you can get things started on the right foot by
automatically granting all committers of the original project commit
access to the fork, including even those who openly disagreed with the
need for a fork. Even if they never use the access, your message is
clear: there are disagreements here, but no enemies, and you welcome
code contributions from any competent source.