Skip to content

Three more checks that were claiming, or not saying, what they knew - #23

Merged
FlagshipDev merged 1 commit into
mainfrom
publish/2026-08-10-94ccfff
Aug 10, 2026
Merged

Three more checks that were claiming, or not saying, what they knew#23
FlagshipDev merged 1 commit into
mainfrom
publish/2026-08-10-94ccfff

Conversation

@FlagshipDev

Copy link
Copy Markdown
Contributor

All three are the same defect wearing different clothes, and it is the one this product exists to
find in other people's software: a check whose answer is a story it tells itself rather than
something it went and looked at.

A check that was told where to look and did not

hullwork status on a healthy deployment reported, permanently:

deployment: not checked: no environment file at .env, so nothing here can compare what you
configured against what arrived. Point HULLWORK_DEPLOYMENT_ENV_FILE and …

The instance had done every single thing that message asks for: the variable set, the file mounted
read-only at exactly that path, the compose passing it to both services. The message names .env,
the default, because status never read the setting.

Three call sites resolved the same pair of paths and only doctor honoured the configuration. The
setting exists because inside a container the working directory holds neither file, so the check
silently never ran on any real deployment — that fix reached one place of three, and one of the two
it missed is the command an operator actually looks at.

What was dark meanwhile is not an ornament: it is the mechanism that catches a variable is correct
in the file, correctly read, and never arrives
, which is the state where a feature reports itself
unconfigured — true of the process and false of the machine. Its second half compares the file
against the neighbouring compose, and that is a real past failure where enrichment had never once
run in production.

There is one resolver now, and a test asserts by construction that no call site builds the path by
hand again.

The manifest error that sent people to delete a line they meant

Adding an optional field to the manifest means a build that does not know it refuses the file:

autofix.open_upgrades: Extra inputs are not permitted (got: True)

Correct, and it says nothing about the possibility that the field is simply newer than the binary
reading it — which the schema version exists to say, but only when the file declares a higher
version, and that field is optional and nobody writes it. The refusal now names the schema this
build understands, beside the offending field and never in place of it: most unknown fields are
typos, and sending somebody to upgrade over a missing letter is a worse answer than the wall was.

The schema version itself stays where it is. Adding an optional field with a safe default is not a
schema change, and a number that increments on every added key stops telling anybody whether their
existing file still means what it meant.

The issue that did not carry the error

An issue filed from a production error contained a lane, an occurrence count, a first-seen timestamp
and a fingerprint. No exception message, no location, no link. A person opening it could not act on
it without knowing a tracker existed and searching it by hand.

All of it had been fetched and stored: exception type, culprit, stack frames, release. The agent's
brief renders those, and has for months, because a brief without them was measured to be worthless.
The person was never given the same courtesy, and two items sat untouched for four days as a result.

Now the body carries the exception type and its full message — untruncated, because providers cut
titles at 100 characters and for a KeyError the half they cut is often the input that reproduces
the bug — the culprit, release, environment, when it happened, frame locations innermost last, and
the link.

Locations only: no variables, and no source lines. A captured variable can hold a credential and
this body is republished into a repository; source lines go stale as the code moves, and the link is
one line above them. The body says so, every time, because what a report leaves out should be a
decision somebody made rather than a default nobody chose.

An issue's body is written once, at creation, and enrichment usually arrives afterwards — so that
alone would fix the next issue and none of the existing ones. When the detail lands for an issue
already filed, it arrives as a comment.

Verified

Twenty defects reintroduced across the three, and the tests that failed to catch four of them were
rewritten rather than counted as passes:

  • one measured a cache window and called it idempotence;
  • one passed because an exception was being swallowed, so nothing was posted was true while the
    code was doing the wrong thing badly;
  • one asserted what a message says and nothing about where it stops, so gluing a hint onto every
    failure — including ones it has no reason to believe — went unnoticed;
  • one guard turned out not to be what makes its property true, and is now labelled as defence in the
    code rather than sold as the guarantee it is not.

Signed-off-by: Javier Miralles Rancaño 68760931+FlagshipDev@users.noreply.github.com

All three are the same defect wearing different clothes, and it is the one this product exists to
find in other people's software: a check whose answer is a story it tells itself rather than
something it went and looked at.

## A check that was told where to look and did not

`hullwork status` on a healthy deployment reported, permanently:

    deployment: not checked: no environment file at .env, so nothing here can compare what you
    configured against what arrived. Point HULLWORK_DEPLOYMENT_ENV_FILE and …

The instance had done every single thing that message asks for: the variable set, the file mounted
read-only at exactly that path, the compose passing it to both services. The message names `.env`,
the default, because `status` never read the setting.

Three call sites resolved the same pair of paths and only `doctor` honoured the configuration. The
setting exists because inside a container the working directory holds neither file, so the check
silently never ran on any real deployment — that fix reached one place of three, and one of the two
it missed is the command an operator actually looks at.

What was dark meanwhile is not an ornament: it is the mechanism that catches *a variable is correct
in the file, correctly read, and never arrives*, which is the state where a feature reports itself
unconfigured — true of the process and false of the machine. Its second half compares the file
against the neighbouring compose, and that is a real past failure where enrichment had never once
run in production.

There is one resolver now, and a test asserts by construction that no call site builds the path by
hand again.

## The manifest error that sent people to delete a line they meant

Adding an optional field to the manifest means a build that does not know it refuses the file:

    autofix.open_upgrades: Extra inputs are not permitted (got: True)

Correct, and it says nothing about the possibility that the field is simply newer than the binary
reading it — which the schema version exists to say, but only when the file *declares* a higher
version, and that field is optional and nobody writes it. The refusal now names the schema this
build understands, beside the offending field and never in place of it: most unknown fields are
typos, and sending somebody to upgrade over a missing letter is a worse answer than the wall was.

The schema version itself stays where it is. Adding an optional field with a safe default is not a
schema change, and a number that increments on every added key stops telling anybody whether their
existing file still means what it meant.

## The issue that did not carry the error

An issue filed from a production error contained a lane, an occurrence count, a first-seen timestamp
and a fingerprint. No exception message, no location, no link. A person opening it could not act on
it without knowing a tracker existed and searching it by hand.

All of it had been fetched and stored: exception type, culprit, stack frames, release. The agent's
brief renders those, and has for months, because a brief without them was measured to be worthless.
The person was never given the same courtesy, and two items sat untouched for four days as a result.

Now the body carries the exception type and its full message — untruncated, because providers cut
titles at 100 characters and for a `KeyError` the half they cut is often the input that reproduces
the bug — the culprit, release, environment, when it happened, frame locations innermost last, and
the link.

**Locations only: no variables, and no source lines.** A captured variable can hold a credential and
this body is republished into a repository; source lines go stale as the code moves, and the link is
one line above them. The body says so, every time, because what a report leaves out should be a
decision somebody made rather than a default nobody chose.

An issue's body is written once, at creation, and enrichment usually arrives afterwards — so that
alone would fix the next issue and none of the existing ones. When the detail lands for an issue
already filed, it arrives as a comment.

## Verified

Twenty defects reintroduced across the three, and the tests that failed to catch four of them were
rewritten rather than counted as passes:

- one measured a cache window and called it idempotence;
- one passed because an exception was being swallowed, so *nothing was posted* was true while the
  code was doing the wrong thing badly;
- one asserted what a message says and nothing about where it stops, so gluing a hint onto every
  failure — including ones it has no reason to believe — went unnoticed;
- one guard turned out not to be what makes its property true, and is now labelled as defence in the
  code rather than sold as the guarantee it is not.

Signed-off-by: Javier Miralles Rancaño <68760931+FlagshipDev@users.noreply.github.com>
@FlagshipDev
FlagshipDev merged commit 7098b47 into main Aug 10, 2026
4 checks passed
@FlagshipDev
FlagshipDev deleted the publish/2026-08-10-94ccfff branch August 10, 2026 00:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant