← 1.0.0 scope SAPE-35

Decide what the operator's shell owes — separately, and on purpose

Status
To do
Component
server
Priority
Medium — the answer may be "change nothing"; the decision is the deliverable
Blocked by
Waiting on
a product decision

The thing to notice

The promise this product makes — a caller never writes an expression, so a caller always knows what a call costs — is a promise made to an application, through the driver. The operator's shell is a different tool with a different audience, and it has inherited that promise by default rather than by decision.

That may well be right. An operator who can do things the application cannot is how most databases end up with a query language nobody can bound. But "we thought about the operator and concluded the same rules apply" and "the operator got the application's rules because nobody asked" produce identical code and completely different futures.

What was measured

Store.Explore compiles every command typed at the prompt into an OperationasOperation in internal/store/explore.go. So the operator's vocabulary is exactly the application's shapes, by construction.

And every ad-hoc read through the shell writes to the change log and commits:

s.record(Change{
    Kind:       ChangeRead,
    Collection: access.Collection,
    Key:        access.Key,
    Operation:  &operation,
    By:         Attribution{Operation: "explore", Actor: caller.Actor},
})
s.Commit()

The rows themselves are deliberately not recorded, and the reason in the code is good: a log holding everything anybody read would be a second copy of the database, growing fastest exactly when somebody is investigating. But that is an argument about what is written. It is not an argument about whether a read writes at all, and the second question was never asked out loud.

What follows from it

What this ticket is not

It is not a proposal to give the operator a query language. That would be the same mistake in the other direction, and it is the thing the whole design avoids. The ad-hoc access an operator already has — get, scan, count — is bounded and typed, and nothing here argues for unbounding it.

It is also not a claim that the audit trail is wrong. Recording what an operator looked at is a real property with real value, and a database that quietly forgets who read what is worse than one that remembers.

Acceptance criteria

  1. A written answer to one question: what does the operator's tool owe, and to whom? Not what the application's tool owes. If the answer is "the same things", the reasons are written down and the ticket closes having changed no code.
  2. For each of the four consequences above, a decision: kept deliberately, or changed. A consequence left unmentioned is one nobody decided on.
  3. If the read-logging stays, it is stated where an operator will read it — because a tool that writes when you thought you were looking is something to know before an incident, not during one.
  4. If it changes, ISS-26 is revisited in the same breath, since pointing the shell at a follower is the same question wearing different clothes.

Out of scope