Ay, ay, ay, Agile!

Ay, ay, ay, Agile! is just a small collection of random scenes and fragmented portraits of a software development team. It's all real. I wish I had the imagination to make these things up, instead of living through them. They don't try to be humoristic -nor dramatic-. They don't try to humiliate anyone, protest or even complain. These are just portraits.

The names, naturally, have been changed.

George gets a task to add one of those embedded tutorials/demos which shows a new feature added to the application. In the description of the task there's no explanation at all about what the widget should highlight or show. Going through the original task for the feature, there's still no explanation about how to use the feature or what are the most relevant parts.

George asks the person who built the feature but, even though they give him a general idea of what it is about, they don't know either what should be shown in the demo/tutorial. George complains aloud wishing tasks would be a little better defined.

Agile means less documentation - points out Karen suddenly from the opposite desk.

Surprised, George insists that he thinks knowing at least what he's supposed to do is to be expected.

Agile means less detailed and more open documentation, because documentation is worthless. What you need to do is collaborate more, work as a team - Karen corrects him.

One morning, after about two weeks of the whole team agreeing on pushing a very light “best practices” effort, Tom comes closer and tells me:

I mean… Look, I tried to clean up some small messes I found, I tried writing the JavaScript code in the way we agreed, but… It's the fourth time already that Karen has come slamming me down for spending some time doing things right. I'm sorry, but I won't be doing that any more because I don't want to have Karen on me complaining.

I tell him it's ok. I tell him not to be sorry, that I will be sorry in his place.

The Architect always assumes nobody knows anything. I may have been hired particularly for being “very experienced in JavaScript”, but…

These are jQuery's Promises. You probably haven't heard of them. They are for managing asinchronicity.

Edward, you've got a 14 minutes mismatch in the month of September. Please fix it ASAP. - the Suit, who just a couple of weeks before was assuring everyone that times were merely informative, for ourselves to observe.

In the meeting to explain “the Agile stuff”, before we begin the sprint, Karen insists very emphatically:

Once we begin the sprint, nothing, no task at all can be removed from it.

A week and a half later, just in the middle of the sprint:

Frank, unassign yourself from this task, because we're removing it from the sprint - I hear Karen say.
What? Just like that?

Yes. And if you've already put some time into the task in Jira, delete it. - says Karen, ending the conversation.

A meeting. Me, hired as an expert in the front-end area, Gunther, hired as database expert. We're describing the absolute horror that is the code. We've been hired explicitly to check on the project's quality. It's a mess - we explain. We propose applying some minimal “best practices” at least in what concerns general order and structure.

The Architect has been responsible for the project since its beginnings. He remains silent the whole time. After an hour or so, his only contribution:

Well, since I am Full-stack, I don't have those problems with best practices. Those things come natural to me. But of course the rest of the team may not be so good.

In a certain form in a section of the application, the users may input up to five contact emails. Originally these were validated server-side. It's a Struts application. The form is submitted, goes through Struts valuation and if there are errors, it redirects back to the form with an error message.

When this was built, XHR -AJAX- has existed for some years, and of course smaller client-side validation in JavaScript has existed even longer. Even so, it's almost three years later that they decide that going to the server and back reloading the whole page every time because of a typo in an email is an experience that can be improved. So, let's validate client-side, they think.

The Architect build a regular expression and a validateEmail function in JavaScript. For the following six years, the validation works like this:

  1. When the user inputs the various emails and clicks accept, all the addresses go through the validateEmail function.
  2. If an address is not valid, its index (1, 2… 5) is saved into a hidden field.
  3. The form is submitted to the server anyway.
  4. There's no validation in the server regarding the email addresses in any way. What they do is they look into the hidden field to see if it has been filled.
  5. If it has, then they redirect back to the form again, using that index in the hidden field to highlight the wrong address.
  6. There's only one hidden field, so only the last wrong address is marked as wrong. If the user, following the highlight hint, only fixed that one, the whole process is repeated, with a new request, redirection, full page load to highlight the next wrong address.
  7. It also happens that the regular expression is not very strict and it lets through a lot of invalid addresses. So after the whole process and the added development, the user can still introduce bad email addresses and get them accepted because they're no longer validated on the server at all.

At a meeting about how the team is working and how things are going. Half the team is here. The developers are here, but not the analysts. Michael, the Suit, is explaining with insistence:

It's not us and them. We are a single team! We're all working together! Get this into your heads once for all. You need to change the way you think!

Exactly two minutes after saying that, Michael says:

I will talk to them later, now this is about how you work.

A couple of hours later, as I'm leaving for home, one in the group of analysts sees me looking a bit down and tells me, without me mentioning anything at all:

You need to understand the dynamics of this project. On the one hand there's us analysts; we're here from the beginning. And then there's the other group, the developers, which came in later, about 8 years ago.

There's a component that builds a sort of menu/widget that can execute commands on what the user selects from any data table. It's configured by passing the various texts and the corresponding commands as functions, or as URLs to call or whatever.

One feature is that there's a pre-execution hook, so that you can pass on a callback and there you can allow or disallow the actual execution of the command that particular time.

These callbacks can do some additional form filling before a URL is called or whatever they need. And they can signal of the command should proceed or not but returning a certain value. This is all pretty common and typical.

At the start of the widget's code there's a global (pseudo-)constant defined:

var OPC_CANCEL = true;

There's also an explanation in a comment:

 * ...
 * - preExecOpCB (optional): callback is executed before calling the command itself.
 *   Thus callback can return OPC_CANCEL (true) to cancel execution of the command
 * ...

Notice how the “(true)” in parenthesis is there only as an additional explanation that the value of OPC_CANCEL is that.

In the code, there are around a hundred different occasions where this is used. In every single one of them, the code is written as:

    return OPC_CANCEL (true);

And it obviously fails every time because OPC_CANCEL is not a function. This has always been like this, for 10 years and nobody ever noticed anything.

There's even one place in the code where someone write optimistically writes:

    return OPC_CANCEL (false);

Which doesn't work either, naturally.

Update: Two months after fixing this, Karen notices the change in the repo and asks the Architect if he knows anything about it. The Architect doesn't. He reads the commit, he reads the changes in the code. He seems confused. “I don't know. Maybe they're was some kind of error?”

The Architect never cares about what his team does or about telling them how to do anything.

- No, no, no. You're overcomplicating things. There's no modification service. There are only two services: create a new register and deleting a register which before deleted but now will only mark it as deleted. So, if state changes to voided, you call void. If you want to “un-void” a register, you call create and the create service will find the old voided register and change its state back. But most users don't have the permission to see voided registers; create will then detect this and return an error. And if you want to sort of modify to change the date, what you do is, delete the old one and create a new one with the new date. But if there's already one in the new date you can't do it will give you an error, but the old register will become voided. But don't complicate yourself.

Minutes later, through email:

- We will need to create a new service to make modifications.

Records, by the way, have no key in the table. The date is supposed to work as key as there should be no more than one record per day. There are, of course, more than one record per day.

Next day, I discover that the service that deleted but now just marks as deleted, doesn't delete nor mark as deleted. It hasn't been used for years and will have to be done new again. No complications, of course.

Well, you are absolutely wrong. I've been reading a lot about Agile lately and Agile says no documentation. Karen

I go see the analysts…

Hi. Just one very specific question. I'm doing that MarkEventVoided…
That's already done.

Well, I mean, I'm re-writing it with the changes and…

Yes, but it already exists. It's not doing it; only modifying it. Changing it a bit.

Well, inputs change, output changes, validations change, what was a delete is now an update.

Yes, but it already exists. It's just a modification.

Eh… Ok… Anyway… The question is that if the state…

Yes, that's in the docs. Read the docs.

Yes, yes, but that's the thing. It says in the docs…

It's easy. If it's an admin, you set the state to 2 (proposal_discarded). Else you set it to 4 (accepted_discarded).

Ok, But I wanted to confirm that…

Yes, yes, that's how it's got to be.

…that if you're admin and it's in state 3 (accepted)…

If you're admin you set it to 2. It's in the docs.

But I mean, it's 3 (accepted) and it would become 2 (proposal_discarded). Wouldn't it make more sense if I set it to 4 (accepted_discarded)?

… Ah, yes, in that case. Of course. Isn't it what the docs say?

No, the docs say what you were saying a moment ago.

Well, I'll fix it then. But I mean, it should be obvious. From 1 goes to 2 and from 3 goes to 4.

I've been saving some questions for Gunther, the DB expert they hired to put some order in the PL/SQL mess. After a couple of minor things, I ask about something I've seen in the project a lot.

Is it normal?
Ah… I've never seen it. I mean, maybe something similar, but not used like this and not so widely.

The thing is there are some general tables. These usually contain configurations or small-ish collections of quasi-constant values. Say provinces or available communication types. Stuff which is quasi-constant because while some may look like they may change, they haven't done so in 20 years. There are 3 communication types. They are what they are and that's it.

So these tables have no name; they're called stuff like M123, A77 or D1541). And yes, they are not one or two or a dozen tables. They are some hundreds of little tables. Maybe a total of some twelve to fifteen hundred or so.

They're meant to be used like this. Say you have a certain table where a “communication type” column appears; something like communication_type_el. And so there's an additional collumn: communication_type_tb beside it. This stores the name of the table where the corresponding description to the communication_type_el is stored. You do your query and you would get the communication_type_tb for that row, go to the appropriate table and look up communication_type_el there. You would but in reality you don't. Because the content of the communication_type_tb is of course fixed and constant for all rows. I mean, communication_type_tb is precisely M144. It's M144 for all rows. A Million rows will have a million M144's and always has been the same M144 value.

What they actually do is just query table M144. Like hardcode M144 everywhere it's used. The value in the tables is never read. Querys inserting in the table will insert a hardcoded M144. This is sometimes done in the stored procedure and sometimes it's sent from the Java side. So, yes, M144 is hardcoded in both.

(Not only that. Some of these tables -a fair amount of them- can't really update their content. I mean, sure you can add a fourth type of communication, of course. But… the thing is that for many of these tables, a lot of hardcoded assumptions elsewhere in the code make those updates irrelevant unless code is modified. Not for M144 but there's a JIRA task somewhere that has been stalled apparently for something like two years because on a first look it's just adding one configuration to one of these tables, but to actually make the added configuration work, the effort has been estimated as some two months “or more depending on some unknowns”, and no one wants to risk it.)

Of course, not everything's a downside2). Doing these “general tables” this way, has permitted them to write certain generic utilities. Like… some client-side features which mean that, yes, there may be another dozen or so M144's hardcoded in JavaScript too.

But the saddest thing is just how established the practice is. So much so that people know a lot of the codes from memory. “Article Families? Mmm… that's table D104.”

The Java parts are very well written. Front-end is chaos. And PLs are a mess too. But the Java parts are quite good because it's what I've done most. The Architect

The quote3) is interesting for a couple of reasons. The funny one is that if you actually look at the code base, it mostly consists of a vey large piece of stored procedures, an huge piece of JavaScript and Struts actions which contain a lot of logic but are considered part of the front-end by the Architect and thus not part of “the Java parts”, and finally a quite thin layer of services which almost only do two things: pass values around in one direction or the other and control access through permissions. So “the Java parts” are mostly mechanic.

They do contain some small pieces of code that go beyond this. But… it's stuff like this:

Let's do some utilities to convert from Array to List and vice versa. Because… uh… Collections.toArray and Array.asList have only existed for 10 years already. And besides… those can work with any kind of item but we are going to write our utilities to only work with Strings, because we move all our data as strings anyway. Oh, and since we're doing our particular converters, we're going to change this weird behaviour: If the array/list is empty we won't return an empty list/array; we'll return null. This will help us avoid a lot of errors.

Yes, the Java parts are “very well written”.

Every time they tell me some task is “an architecture task” what it means is that it's something they don't know how to solve. That's all there is to “architecture”.


I'm going to send you a JIRA for an architecture task. IT's about the front-end side, of course.

The task: writing a stored procedure in PL that returns a two dimensional array. Stored procedures are also front-end, I guess?

The Architect invites me for a meeting at 11:00. And so, at 11:20, we finally go to the meeting room for a presentation on “what shall be the new Architecture I've come up with for all our future auxiliary applications”. They want this to fit for everything they do in years to come. I am here because they want my opinion on this decision, the Architect tells me. Besides us, there are two other developers who, apparently, already know about this proposal.

Woho! We got a whiteboard…

The Architect's eyes light up. He draws a box where he writes “Rest” and to the side of it: “API”. Inside the box he scribbles something that looks close to “Spring Boot”.

This part does not worry me. This has already been decided and it's correct.

He draws a second box. Over it he writes “Front”; inside “HTML5, JS, CSS”. To its right: IONIC.

Basically, we've thought about using HTML5 with Ionic for everything on the front-end side.

The next 30 minutes go by exchanging a number of anecdotes on applications they did in the past or had some sort of relation to, but which, they mention, may not represent upcoming needs.

Finally, the question for me: Do I concur with this or do I not? Or to be more precise: that I should concur. I ask if we have any idea of what kind of requirements these potential future application will have. It's not clear, something generic, “usual stuff” - they say. “We expect that if some particularly demanding requirement comes up, this Architecture may not apply; but that wouldn't be common.”

He explains again that he wants to know whether I agree with the decision or not, if I see any concerns or difficulties. By his tone it's very clear he wants me to agree and to have no concerns. Inside my head I'm saying it doesn't matter if they choose Ionic or Bubonic. Out of my mouth comes something more cautious, though.

Well, without knowing what these future applications may be about or what requirements they may have, it's a bit difficult to answer, and I don't think there will be much of a difference between choosing Ionic or anything else.

I try to explain that what they need to know is what they will be using this “new Architecture” for. That it doesn't matter so much which libraries they choose. But as soon as I utter that “without knowing what…” above, the Architect is no longer listening. He's just trying to interrupt me with increasing volume.

I just let him interrupt me and he once again explains that it will be “usual stuff” for a couple of minutes. He then explains again too that the meeting is “just so that I can give them my opinion and what I think about it”. Ok, so… he wants me to agree with his already made decision and say it looks ok. And I can see in his face he's getting somewhat impatient as it's the third time he insists on this same idea.

I give up, say Ionic is ok, even though I don't think it really matters that much. But yes, yes, I agree. Ionic.

The Architect lights up again and concludes the meeting as a success. He announces some “next steps”, which for some unknown reason include him installing VSCode in my computer. I let it pass knowing that will never happen.

As I'm walking back to my desk, I hear behind me one of the other two developers ask the Architect what JIRA task should he put this hour on.

Today is visiting day. Directors, Area Managers, Generals and some other high-ups are coming.

Today it's time to pretend. There's no beach shack music in the background all day long, with the accompanying whistles from the guy who thinks he knows how to whistle. The break is taken earlier and it's kept to the official 20 minutes duration instead of almost an hour so that the place isn't deserted when visitors come. One of the Suits has even spent some minutes smoothing and disentangling the window curtain that is always wrecked up and entangled. It's still a sorry sight, but a little less so. The paper canvases are almost never used and lay waiting in a corner for a friendly pen to write something on them; today they are not in a corner but all ready for nobody to use them but give the appearance that someone actually does.

Today is all a lie. Today is all theatre.

They warned me and I didn't listen. Karen is “spiteful and vindictive”, they told me. I ignored it because such comments are better left ignored.

Some days ago, though, I made a massive change. Actually it wasn't so “massive” at all. Compared to other changes I've had to do, this one was relatively small: 25 JSPs. Unfortunately I broke one of them without noticing. So yesterday Karen was altered, threatening me, telling me I couldn't make those kinds of changes, that this would have to change around here.

I fixed the problem in a couple of minutes, and I make these changes because a. they are necessary and b. I was hired explicitly to make them, because they know they are surrounded by trash and needed someone to take out some of that trash. Also, the breakage happened in a testing environment, not in production, of course. And this environment is there exactly for this problems to happen on it. All this is irrelevant, of course, because Karen's look was telling me she didn't care about any of that. Karen never cares about those things anyway.

Today Karen casually tells me two things. “Trunk is closed”, she says meaning they've put the repo on read only -which they do every time they deploy to testing, about once every couple of days-. She also tells me she's going to give me some bugs to look into. So she starts sending me any bug she sees on JIRA. I fix some but… alas, trunk is closed so I can't actually commit my fixes. I innocently tell Karen and she tells me trunk is closed -which I already got- so I should go on fixing errors and tomorrow we'll revise them and decide.

She insists that trunk is closed which I don't really give much thought to until a while later when I discover -no surprise, really- that this is not the case. Trunk is closed for me. The rest of the team can freely commit whatever they need to. But not me.

So I comment on JIRA that I've fixed the errors locally and then I go around telling them those critical errors they need to see fixed in testing so that they can test other stuff, will have to wait a bit. I don't say anything else, but I know what we're waiting for is for someone to take the nap they need.

Next day, a little before the deployment process is set in motion4), Karen casually goes off for a break for half an hour or more. I'm still on time-out; the fixes will not be deployed for a couple more days at least.

While trunk is closed for me, the Architect pushed a change which has indeed been deployed and casually breaks every page in the application. He jokingly downplays it:

Well, it's not my fault. It's Steve's fault for deploying it. Ha, ha, ha.

Karen laughs awkwardly, as she can't do anything against the Architect.

The best strategy against these power games is not to play. They end up playing themselves.

They hired me because they needed someone that really knew JavaScript well, they told me. Someone with lots of experience on the front-end side of things.

The Architect is explaining not too clearly to one of the analysts that setTimeout is better than setInterval “because it works better with asynchronous events” - he says. He's explaining it so that the analyst in turn explains it to the developer that always reminds me she's not really a developer, that she went through some light training and then threw an existing application on her.

Apparently they have a problem where, some times, the browser freezes when opening the window where they load a map viewer. The Architect speaks with confidence:

It might be because of setInterval… Well, there's some errors you just don't know what it can be…

Obviously, even knowing I offered to look at it, nobody considers asking me for help. And, honestly, I feel lucky for this. It's a function5) written by a developer who openly declared he wasn't interested in anything I might tell him. The function is filled with nonsense and unnecessary usages of this.

The Architect is now saying how much he would like to take some time to try doing this using postMessage because, he says, “we would avoid all cross-domain communication problems with that”. The map viewer is served from the same domain that serves the rest of the application. But that's irrelevant, because the Architect would like to try that, even if it's completely unrelated to solving the current problem.

That Glassfish thing I think it's a new server from Oracle. The Architect. Nov. 2019

Two weeks later I'm still grounded with no access to Subversion. And it's not only trunk. I can't commit anything to the development branch either.

As power demonstrations go I would feel impressed6) if it wasn't for the fact that I don't really care about it at all.

This one is a “find”. This one is a “search”. This one is this one. The Architect, being especially clear in his explanations.

They're doing this project on the side that would be an example of how things should be done.

The field endDate… is it required? - asks Geoffrey.
Don't know. I don't remember how I set it. Write a unit test, set it to null and see what happens - says the Architect.

It reminds me that this is how they write “unit tests”7) when they do write them. They don't write them to assert what should happen, just to see what happens.

The tests are, naturally, deactivated on the build. There are around 20 tests. They take about 15 minutes or so to run.

It's a project that should set an example. And yet nobody had even thought about writing a readme, or any install instructions at all, or even any sort of development guide or any documentation at all.

Long idCode = null;
idCode = idCode.parseLong("612");

The Java parts. They are quite well written because the Architect wrote them.

So they are doing some stress tests…

“The weblogic server is at 100% on RAM”, - says Marcus, the systems department. “It's running the file upload test.”
“That's quite natural. I optimized that for maximum RAM consumption”, - says the Architect. “It runs 5 passes over the XML for each request…”

“But it's maxing out on just 5 concurrent uploads. What if a hundred users start uploading stuff at the same time…?”

“Nah. That won't happen. Besides blah blah blah and so in any case it would be a network error. Not my problem.” - the Architect doesn't actually say “blah blah blah” but his words sound curiously close to that. Much longer, though.

Two weeks later…

“We didn't pass the stress test… I don't know why.”

Time obsession. Back from Christmas I have an email explaining that the time spent on the little celebration they had on the 23rd, should be put on this or that JIRA task…

Can you lend me a hand here with this JavaScript thing?
Sure thing. Tell me.

<… He explains the problem…> …and the first thing I thought was using promises. So I've done this and that…

I see… But you didn't need a promise here. You can more easily do this and this.

Oh, I see. That's great. Thanks. But out of curiosity, why want the other thing working?

<… explanation about events, asynchronous stuff and variable initialization and execution order…> But… wait a moment… What do you know about promises?

Oh, almost nothing at all. I know they sort of like… let you wait for things or something, but the truth is I've never used them and I don't know what they are.

I don't blame him. I know a large part of the blame is they've had no training at all for years. But… I don't know, maybe if you don't know what something is, don't let that be the first thing you think of to solve something.

The Architect, who knows a lot of Java, just casualty commented he has no idea at all about log4j and what logging levels mean.

There's a concept that clearly shuns away from the Architect. I'm convinced there are many concepts that do, but this one in particular is “ending a conversation”. The Architect doesn't end conversations; he exhausts them, he squeezes them dry, hits them until they are dead.

I've already told about how he insistently repeats himself until people agree, and how he interrupts every one and monopolizes the conversation. But this goes a bit further.

I almost fall into the trap today. Seven minutes before leaving, he asks me about accessing the clipboard from JavaScript. As usual, he'd done some clunky kludge and was seeking approval. And I was immediately reminded of this scene I've seen play often…

The start of the scene doesn't matter that much. Sometimes someone comes to his desk, sometimes the Architect is at some informal meeting with four or five people. Or maybe he's strolling happily through his domains, surveying, looking for someone to spend an hour or two discussing.

Whatever. The conversation starts. And then it goes on. And on. And it keeps going on and on, running around the same things, without ever reaching any sort of conclusion.

Others do reach a conclusion. Myself, I've concluded many times that the Architect is only taking in front of you, but he's not speaking with you. He talks to himself.

Oh, ok, but I digress… Others do reach a conclusion. After 30 minutes or 3 hours, you hear them say “Ok, then. I'll try that” or “Ok, so I'll do that and get back to you” or some other formula that tries to be polite but still communicate “We're done here; conversation is over now”.

Not just that. They physically end the conversation. They leave. They stand up and walk away. Maybe they explicitly mention going out for a cigarette or to the restroom or some other with enough distance in between.

And then the Architect follows them.

He stands up to and walks with them, words still coming out of his mouth. Maybe he repeats something he already said, or maybe he goes back to something else they talked about earlier.

And the conversation still goes on. Now in the corridor, or at the victim's desk, or maybe just give it six steps away from the previous place. I can remember once hearing him say “Ah, I'll go to the restroom then too” only to continue taking on the way, while there, and on the way back.

The only thing ice found that works is awkward silence. When I'm done, I just don't say anything else at all. He goes on? I say nothing. Only then will he consider the conversation finally exhausted.

Or almost exhausted. Because I've noticed when I do this, as his desk is just opposite to mine, he will sometimes mumble something after a minute or so. At a volume tuned so that I can clearly hear him, and that can be interpreted as still taking to me or as just thinking aloud to himself.

You need to resist. Even if what he says it's wrong -which happens often-. It's time to go home and I'll gladly let him stay here all weekend talking to himself.

One day, the Architect shows me one of his kludges. A particularly bad one involving Promises and callbacks intermixed when neither is actually needed.

I tell him, succinctly, pointing out a much, much simpler solution. He says something like “but it's asynchronous, I need the promise…”. I show him, trying not to make it sound like his code is absolute idiocy but just that it can be done a lot simpler.

He seems unconvinced but says:

Ok, I understand. Of course the idea is to do it in the best possible way. I'll give it another try.

I turn back and walk to my desk which is all but 1 meter away. Maybe two seconds. Three max before I'm seating at it.

In those three seconds, the Architect has already committed the code to Subversion. On trunk, of course.

A couple of minutes later I hear him talk to someone else about his thing.

And it's asynchronous, so I had to use these promises and callbacks here. It wasn't easy solving it.

When I got here there were two Agile boards in the room. Well, they're just a bunch of large paper pieces on the wall pinned there with some masking tape. On them, some post-its.

One is the kanban board for the development team. The other one belongs to the “Technical Office”, which is Karen, the Architect and both Suits. This one's got typical three sections/lanes -pending, in progress, complete- and it lives on the wall just behind Karen's and the Architect's desks.

When I got here, this board had 21 post-its on it, most of them with a single letter or two (CJ, P, BD, and so on). I don't know that it had 21 post-its when I arrived because I counted them at the time. I know because after 9 months they are exactly the same post-its in the exact same places as they were then.

At least until this morning, as it seems tonight some of the tape gave up and a whole section fell to the ground.

When he got here this morning, the Architect didn't seem to even notice. Karen did. She pushed the piece into a corner so it wouldn't be stepped on, and left it there.

Later someone has folded it up into a less bulky thing and moved it somewhere where it will be left forgotten for the rest of its life.

And the other board, the development one? Oh, that one has one post-it demanding Serrano ham, another one with a fussball table drawn on it, and one asking for whiteboards. It was used for about one month before falling into abandonment.

El tablón, ahora solo tablc

Dylan, to my left, has been looking through something with the Architect for ten or fifteen minutes.

Ok, thanks. I think I now know which way to go - says Dylan.
So you'll have to debug this and blah blah - the Architect goes on

Yes. Right. I can take it from here.

Blah blah…

That's enough, really. I can do it on my own.

Blah blah…

Sure, but really I can debug through this.

Blah… - suddenly the Architect grabs the mouse off from Dylan's hand and says: - Just press Alt+Shift+P.

The Architect is over at Maxwell's desk looking at some sort of problem. After a while of touching this and that, the Architect very seriously reaches a conclusion:

The problem is that something weird happened.

And says nothing more.

For some reason I like this Jira plot on Business Value Delivered…

Valor para el negocio

I tell Lizzie I'm looking into the problem she told me about but that I'm going slow because the query seems to take very long…

Yes, it does take a little…

And that's all there is to it. The query takes a long time. We know it. Such is life. It takes about an hour and a quarter. Click, 1h15m, results. Fine.

Karen is talking to Montgomery, two desks to my left. I have my headphones on, trying to escape from all the background music and the noise from the industrial-sized AC. So apparently I don't hear Karen, but truth be told I paused my music just a moment ago and I hear everything.

Karen leaves and goes over to someone else. Says something, moves on to the next. She reaches Lizzie and Steph, sitting behind me, and repeats her message.

She's not exactly whispering but she does talk one or two notches below her usual volume. She tells them the same she's telling the rest. Karen says:

We're opening trunk on the repo for a while. If there's anything you need to get in the next deploy tomorrow morning, commit now, ASAP, please.

Karen thinks I can't hear. I know because she goes around and tells everybody… Everybody but me. At one point I catch her in the corner of my eye looking at me from a distance.

I do have a couple of fixes that should go on the deploy tomorrow, but apparently they'll have to wait some more. Maybe next week, if Karen feels like it, I guess.

Next morning after deployment is done and announced to the team, someone asks me about my fixes. “I don't see it fixed on the testing environment” No, obviously. I explain that Karen didn't consider I should upload my fixes yet.

I'm gonna tell the Suit, because this was an error that exists in production and it should've been deployed.

Off she goes. Talks to the Suit. Then the Suit speaks with Karen. Then the three of them talk. At no moment they consider talking to me. I guess I'll keep waiting to commit my fixes.

Unofficially, quietly, someone tells me she heard Karen deny the whole thing, and that I can commit to trunk like anyone else. Eh.

Next deployment I can finally upload my fixes. Maybe it's just a coincidence but this time Karen isn't around. She told Tricia to tell us about the deployment while she needed to be somewhere undefinedly else.

Oh, noes! The horror! The terror!

Something bad happened. Something very bad. Something so bad, so urgent, that we're all summoned immediately to an emergency meeting. Everybody drop everything right now and come.

The Architect tells a very emotive story about Oracle versions and the support for DATE, TIMESTAMP and java.sql.Date and how, for reasons completely unrelated to him and that he could've never anticipated in the last five years, there are now some problems in the application because some procedures, failed to correctly choose if they needed just a date or a timestamp.

It's totally unexpected, unpredictable, totally Oracle's fault; it's absolutely not the consequence of having chosen to abuse an existing bug to cut corners. Not at all. But don't worry, the Architect knows what to do. Analysts and developers will be the ones doing the actual work; boring, tiresome work, but such is life.

He explains briefly and without much detail the fix: use DATE where you need it and TIMESTAMP where you need it. That's all.

Karen, to his side, adds, trying to calm people:

This will, of course, be added to the Best Practices Guide on the wiki, so that anyone can see how to do it correctly.

As soon as she finishes saying it, I know that won't happen. Three weeks later, as expected, it hasn't happened. The Architect never documents anything at all.

Another two weeks later, Gunther confirms that the problem is still there. The analysts are looking at it… when they have time. Calmly, no rush. It will take time.

Gunther, the DB expert, embarrassedly confirms my suspicions with a mix of shame and scandal:

Yes… They do all data migrations by hand. The analysts, they say they prefer it that way. They call it dusting.

They always do it that way, by hand, live on production DB. They like being little cogs in the machine. Makes them feel in control.

function alerta(a){alert(a);}

There's a prevailing trend among the developers in the team. They just aren't interested at all in the tools they use. They don't install them, they don't configure them, for some operations they don't even use them, asking instead someone else to do it for them.

A moment ago, Reginald got an error running Maven. He told the system admin to fix it and went out for a cigarette while he does.

The Architect always speaks of the code as if he'd written all of it. Almost as if it was part of him. “When this happens, I do this other thing.”, he says describing a condition in the code.

He always speaks this way. Always… except when something's wrong. “Let's see what shit you people are doing here” or “It looks like you have an infinite loop in your code.

That will be done automatically when all changes are ready. But, of course, when I say automatically I don't mean click and it's done. We need to go one by one doing it manually.

Karen, redefining words as she goes.

Montgomery asks for my help. Montgomery doesn't really know how to ask for help. He just says “Can you come for a moment?” and, of course, I drop everything and go for a moment. He doesn't explain the problem but instead starts clicking around going to the code, expecting me to guess or something. What happens is he doesn't know how to explain the problem or exactly what he's doing.

Finally, after a bit of going back and forth, I understand: he wants something impossible. He has a component that is too big for the space he has, and he wants it to fit in that space without making the space bigger nor the component smaller. But he doesn't seem aware of the impossibility.

We spend some time explaining and looking for a different approach. I'm going slow and steady. We're getting there and then a light tap on his shoulder.

Time for the mid-morning snack.

And off he goes. He says we'll continue later and goes. He won't be back for an hour and a half and when he is, he remembers nothing of what we were doing.

Part of my job8) is writing documentation. I'm cleaning garbage and writing an explanation of how not to produce the same garbage again but do it a bit better. Maybe there are 14 different functions to open a simple window for information or confirmation? Well, then we unify and then write in the docs how to do it so that every body does it the same way. And maybe, perhaps, so that the Architect stops writing yet another function to do exactly the same but in a slightly different way with the same small nasty bugs. Oh, fat chance.

Anyway, the docs go in a MediaWiki where unfortunately syntax highlighting is not correctly installed9). At first I was bummed. Enough to ask Marcus, the systems department, if we could have it fixed. Not only so that the docs look better but also because all pages trying to use it are marked as errors. Ah, well, I would like it if it worked, particularly since the docs are about code and have a bunch of it. But no, it doesn't look like we can have that. I don't blame Marcus, the systems department, because he's always got a lot or work, but I asked about six months ago.

So, while I was thinking about this and how much better the docs look with syntax highlighting, I decided to go in a different direction. I now use Carbon and I insert the code as an image. Really despicable, I know; you can't select the text and copy and paste it. But then again… I really do not want them copying and pasting. I want them to type the code.

Nobody has complained yet, but I suspect this is mostly because only one or two of them actually read the docs anyway.

Each letter corresponds more or less to a certain section of the application
which is, of course, real
it takes a couple of hours or three
actually there are I think four just slightly different functions
Wooo, such power
or what they call unit tests
maybe the only part that makes some sense and can be done without fighting
It's missing Pygments or some parts of it maybe