RAMYA LAKHANI

All log entries

What I was doing. The ASK box on this site answers only from published work. Nothing is published yet, so I made the client check that up front: if the corpus is empty, bail out early and leave the submit button disabled.

What I noticed. It reads as broken software. You type a question, press Ask, and nothing happens — no error, no explanation, no state change. A reader cannot tell the difference between “this site has decided not to answer you” and “this site is broken”, and they will assume the second one, because that is the more common explanation for a button that does nothing.

The refusal already existed on the server, and it was a good one:

{ "reason": "no_published_source" }

which the interface renders as “Nothing published here covers that. ASK answers only from what is published on this site. No published source, no answer.”

That is a better outcome in every way. It is specific, it is honest, it states the rule, and it arrives as a response to an action the reader took. Deleting the client-side guard made the feature work by making it fail properly.

Why it matters for shipped code. Gating a control client-side to avoid an answer the server will give anyway trades a clear rejection for an ambiguous silence. The pattern shows up in permissions especially: hiding the delete button for users who lack the right is fine, but if the reader can still reach the action and nothing happens, they learn the product is unreliable rather than that they lack permission.

Two rules I would now apply in review. The server owns the refusal — the client may reflect it, never substitute for it. And an inert control is a bug report waiting to be filed; if a control cannot act, it should say why at the moment it is used.

Open question. There is a real case for disabling a control: preventing an expensive request that is certain to fail. I do not have a clean line yet between “save the round trip” and “hide the reason”.