How Would We Know We're Wrong?
The previous nine articles have built a hypothesis and traced its consequences. This article is the test. If the test fails, the series ends here and no packages are built. If the test succeeds, the smallest viable kernel ships and the series gets a follow-up post documenting what survived contact with implementation.
The test is one tiny diagnostic, deliberately small. The smallness is the point: a multi-phase rollout on a hypothesis this speculative would be exactly the wrong move. Ship the smallest thing that can either survive or die quickly, see what falls out, then decide.
The diagnostic, stated precisely
Pick exactly one existing @Feature from @frenchexdev/requirements-requirements — the dog-food package that contains the requirements DSL's own requirements. Call this feature F.
Perform the following five steps:
- Read
Fand its current decorations. Note its@Satisfies(R1, R2, ...)linkage, its acceptance criteria, its test class via@FeatureTest, the@Verifiesdecorations on each test method. - Manually extract what the intention behind
Fwould be. Write it down in plain English. Then encode it as a hypotheticalIntention<I_F>declaration — name, purpose, scope, refinements if any. - Re-project
I_Finto the existing kernel. Working only fromI_F, write what the Feature, the acceptance criteria, and the Requirement linkage should be under the hypothesis. Do not look atF's current shape while doing this; produce the re-projection independently. - Compare the re-projection against
F. Note every divergence: every AC that the re-projection has andFdoes not, every Requirement linkage that the re-projection produces andFdoes not, every test that the re-projection would generate andFdoes not have. Also note the converse: ACs inFthat the re-projection does not produce, Requirements inFthat the re-projection does not surface. - Categorise the divergences. Each divergence falls into one of three bins:
- Bin A: re-projection surfaces something
Fis missing. The hypothesis has produced a real gap in the existing artifact. This is the case the hypothesis predicts: the intention framing catches things the requirement framing misses. - Bin B:
Fhas something the re-projection cannot produce. The intentionI_Fis under-specified, or the framing has a blind spot that the requirement framing covers. This is evidence against the hypothesis, but not necessarily fatal — it might indicate the intention needs refinement, not that the framing is wrong. - Bin C: the re-projection and
Fagree. No information is gained or lost. The hypothesis is decorative for this particular case.
- Bin A: re-projection surfaces something
The decision rule
After running the diagnostic, the decision rule is:
- If Bin A has at least one substantive item — something
Fis genuinely missing that the re-projection caught, where "substantive" means a failure mode I have personally seen and not a hypothetical gap — the hypothesis is alive. Proceed to build the operational tree from Part 9, starting with the two-package collapsed version. - If Bin A is empty or has only non-substantive items — the re-projection produces the same artifact
Falready produces, with no new failure mode catches — the hypothesis is dead. The series ends here. No packages are built. The articles stand as a record of a hypothesis that did not survive a small honest test. - If Bin B has substantive items that cannot be repaired by refining
I_F— the framing has structural blind spots and the hypothesis is, at best, partial. The decision depends on whether Bin A's substantive items outweigh Bin B's. If they do not, the hypothesis is dead.
The rule is asymmetric and intentionally so. The hypothesis is the novel claim; the existing kernel is the known good. The asymmetry says: do not replace the known good unless the novel claim demonstrably catches something the known good cannot. Skepticism toward the new is the default; the burden of proof is on the new.
Why this particular Feature
The choice of which @Feature to use for the diagnostic matters. The choice should not be a Feature the framing was designed against — that would be confirmation bias. The choice should not be a Feature so trivial that no failure mode could surface — that would be a vacuous test. The choice should be a real Feature with non-trivial complexity, where the existing @Satisfies linkage has been touched by at least two refactors and where I have at some point had to manually reconcile divergent ACs.
The candidate I have in mind, as I write this, is the Feature that tracks the RequirementStyle workflow pluggability — the Feature that says "the requirements kernel shall support multiple competing lifecycle styles." That Feature is non-trivial (it touches every analyzer, every CLI command, every scaffold), it has been refactored multiple times as new styles were added, and the @Satisfies linkage has shifted enough that I remember being unsure once or twice whether the linkage was current. It is also the Feature where Part 7's requirements-styles precedent applies most directly.
I am not committing to this Feature here. The actual choice will happen when the diagnostic runs. I am noting that some Feature with these properties has to be chosen, and the choice should be defensible — not the easiest case, not the hardest case, a case where I have personally seen the existing kernel produce uncertainty.
What surviving looks like
If the diagnostic surfaces a substantive Bin A item, the next step is the smallest possible build. Not the operational tree from Part 9. Not even the two-package version. The smallest possible build is:
- One file defining
Intention<T>andExtension<I, K>as TypeScript types, in a new directorypackages/intentions-poc/or similar. - One decorator for the extension kind that the diagnostic surfaced — probably
@MethodExtensionor@ClassExtension, whichever the Bin A divergence pointed at. - One concrete usage — the Feature from the diagnostic, re-projected as a working artifact, side-by-side with the existing Feature.
- One test (using
@FeatureTestand@Verifies, neverdescribe/it) that runs the re-projection's analyzer and demonstrates it catches the gap that the diagnostic surfaced.
This is a working prototype, not a package family. It exists to prove the diagnostic was honest — that the gap the diagnostic found in the existing kernel can be caught by the proposed kernel in a real implementation, not just on paper.
If the prototype works, the next step is the two-package operational tree from Part 9. If the prototype falls apart on contact with implementation — if the analyzer turns out to be impractical, or the registry surfaces too much noise, or the decoration ergonomics are intolerable — the hypothesis dies at the prototype stage and the series still ends without packages.
The exit clauses are layered: the diagnostic can kill the hypothesis; the prototype can kill the hypothesis; the first real consumer can kill the hypothesis. Three chances to discover the framing was wrong, before any operational commitment is made.
What dying looks like
If the diagnostic produces no substantive Bin A items, the hypothesis dies and the series ends. There is no "second chance" diagnostic, no "let me try one more Feature." One Feature, chosen in advance with defensible criteria, one comparison, one decision.
The dying does not mean the series was worthless. The articles stand as the record of a hypothesis that was taken seriously and discarded honestly. The shape of the discarded idea is itself useful for the next idea: I know now what Intention and Extension would have to look like to be useful, which means I know what other upstream concepts (purpose, motivation, rationale, etc.) would have to look like if any of them turn out to be the right name for the thing the framing was trying to point at.
It also means I keep the existing @frenchexdev/requirements-* family without modification, knowing now that its kernel was correctly placed. The series did not break anything; it confirmed the existing architecture is at its natural level.
What stays open after the diagnostic
Even if the diagnostic survives and the prototype works, several questions stay open and I want to record them as the next design-in-public series, not this one:
- How does the intention framing interact with bounded contexts when both are present? The DDD overlap from Part 5 becomes pressing once both abstractions are real.
- How are intentions discovered or written, organisationally? Are they extracted from stakeholders, derived from existing code, written by architects? The provenance question is not addressed in this series.
- Can intentions be inferred? Given an existing codebase with
requirements-*decorations, can a tool suggest what the intentions behind the existing Features are? The auto-inference question would dramatically change adoption ergonomics. - How do intentions evolve? The
IntentionStylelifecycle from Part 4 gestures at this but does not work it out. The evolution question is its own design problem.
Each of these is a series-shaped question. None of them get answered here.
The closing register
I want to end this article — and the series — in the same register I started it in.
I have a pressentiment. I have spent ten articles examining it. I have engaged the objections I could foresee and conceded the ones that landed. I have proposed a package architecture and then collapsed it. I have specified a diagnostic small enough to run and explicit enough to settle a decision.
I do not know whether the diagnostic will survive. I do not know whether the hypothesis is true. I do not know whether the packages should exist.
What I know is that writing the series was the right move regardless of the outcome. If the diagnostic kills the hypothesis, the writing was the work of taking an intuition seriously enough to test it. If the diagnostic survives, the writing was the foundation that the next, smaller, more concrete work builds on. Either outcome was worth the ten articles.
The diagnostic runs next. If you read this and the follow-up post never appears, you will know which way it went.