Skip to content

Commit 92709fb

Browse files
dmealingclaude
andcommitted
fix(fit-assessment): never infer "won't grow" from a small repo (M8)
The disqualifier table let a small codebase produce a flat NOT A FIT ("< ~3 entities — leverage won't pay for tooling"). But small-today and small-forever are byte-identical in git: a 3-entity app that becomes 90 and one that is finished look the same. The assessment's own evidence discipline (M2: cite file:line) actively pushes toward inferring trajectory from code — and there is no file:line for intent. That's a false-negative generator aimed at exactly the projects worth converting. Split NOT A FIT into its two real families: - STRUCTURAL (language outside the five ports, no relational store, non-entity domain, DBA-gated schema) — genuinely observable; still the only grounds for a flat NOT A FIT. - ECONOMIC ("too small to pay") — decided by GROWTH, which is not in the repo. So: new method rule M8; trajectory promoted to an elicited Input (3) with an explicit "you MUST ask, it is not in the code"; the size row rewritten as a conditional (done-at-this-size -> MARGINAL; expected-to-grow -> FIT, and note adopting later costs more because you retrofit a spine onto more drift); unanswered -> emit BOTH branches, confidence: low, checkable: false, never guess. §R7 must now state the limit plainly: this reads your code, not your roadmap. Added a self-check item 0 gating it. Corollary (also recorded): a negative control for this assessment cannot be *any* small repo — only one whose trajectory is KNOWN (e.g. retrospectively stayed small). Anything else tests a fact the code does not contain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hd5NWZ1rKau63vJzrBSpLb
1 parent a7dbe40 commit 92709fb

1 file changed

Lines changed: 45 additions & 4 deletions

File tree

  • agent-context/skills/metaobjects-fit-assessment

agent-context/skills/metaobjects-fit-assessment/SKILL.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@ and which metadata vocabulary the project isn't asking for but would profit from
3737

3838
1. Repo access (required). For monorepos: which subdirectory/service to scope to.
3939
2. Stack confirmation (detect, then confirm): language(s), DB, ORM, web framework.
40-
3. Whether an LLM/prompt surface exists (scopes pillar 4).
41-
4. Org constraints that gate verdicts: who owns the schema (DBA-gated?); is generated
40+
3. **Trajectory — you MUST ask; it is NOT in the code (see M8).** Is this system expected to
41+
**grow** (more entities, a second language or service, an LLM surface, a team beyond one
42+
person), or is it feature-complete and stable at its current size? Is it long-lived, or
43+
disposable? A repo that will triple and a repo that is finished look **identical in git**
44+
and this is the single fact that decides the size-based verdict. If the human doesn't
45+
answer, do not guess: state the assumption you made and mark the verdict conditional on it.
46+
4. Whether an LLM/prompt surface exists (scopes pillar 4).
47+
5. Org constraints that gate verdicts: who owns the schema (DBA-gated?); is generated
4248
code in the repo acceptable?
43-
5. Where to write output. Default: `metaobjects-fit/` at the target repo root.
49+
6. Where to write output. Default: `metaobjects-fit/` at the target repo root.
4450
**Never create `.metaobjects/`** — that directory is the marker of an adopted project.
4551

4652
No secrets, no live-DB connection. You read code and migrations only; `verify --db` is
@@ -98,6 +104,31 @@ for the target's port (§ P5-b) in one clearly-labeled paragraph, tagged
98104
`horizon: "later"` in JSON and never counted in the benefit numbers. Omitting a real
99105
option a deep adopter would take is a scored defect, just like inventing one.
100106

107+
**M8 — The verdict-deciding fact is not always in the code. Size you can count;
108+
TRAJECTORY you cannot.** The honest NOT-A-FIT splits in two, and only one half is
109+
observable:
110+
- **Structural disqualifiers ARE in the repo** — language outside the five ports, no
111+
relational store, a non-entity-shaped domain, a DBA-gated schema. Read them, cite them,
112+
rule on them. These are the only grounds on which you may write a flat `NOT A FIT`.
113+
- **The economic disqualifier is NOT in the repo.** "Too small for the tooling to pay"
114+
depends on whether the system will **grow** — and a 3-entity app that will become 90 is
115+
byte-identical in git to a 3-entity app that is finished forever. **Never infer "this will
116+
never grow" from a small codebase.** Absence of growth-so-far is not evidence of
117+
no-growth-to-come (a young repo is small *because it is young*). This is the one place your
118+
evidence discipline (M2) actively misleads you: there is no `file:line` for intent.
119+
120+
So: **ask** (Input 3). If answered, rule on it and say whose answer it was. If unanswered,
121+
do NOT pick a side — emit **both branches** explicitly, e.g.: *"At 4 entities today the
122+
spine's leverage does not repay the tooling — if this system is done, don't adopt. If you
123+
expect it to grow past ~10 entities, add a second language, or add an LLM surface, adopt at
124+
that point; and note adoption gets more expensive later, because you will be retrofitting a
125+
spine onto more drift, not less."* Tag such claims `confidence: low` and
126+
`checkable: false` — they are conditional on a fact you were not given.
127+
128+
Corollary for scoring/QA: a "negative control" for this assessment cannot be *any small
129+
repo* — it must be one whose trajectory is **known** (e.g. retrospectively: it stayed small
130+
for years). Anything else tests a fact the code does not contain.
131+
101132
---
102133

103134
## The passes — run all of these BEFORE writing the report
@@ -260,7 +291,8 @@ this table worked row-by-row is invalid output):
260291
| Backend language outside TS/Java/Kotlin/C#/Python | NOT A FIT (codegen/runtime); prompt pillar only if a portable sidecar makes sense — usually no |
261292
| No relational store | persistence + `--db` N/A; assess prompt + value/projection pillars on their own merits |
262293
| DB not Postgres/SQLite/D1 | schema pillar (`migrate`, `verify --db`) OUT — say so plainly; data-access unaffected |
263-
| < ~3 entities or non-entity-shaped domain | MARGINAL/NOT A FIT — leverage won't pay for tooling |
294+
| Non-entity-shaped domain (no persistent typed records to speak of) | NOT A FIT — structural, and visible in the code |
295+
| Few entities today (< ~5) | **NOT a flat verdict — this is the M8 trap.** Small-today ≠ small-forever, and git cannot tell you which. Use the trajectory answer (Input 3): *done at this size* → MARGINAL/NOT A FIT (say so plainly — the leverage won't repay the tooling); *expected to grow / add a language / add an LLM surface* → FIT, and note adopting later costs more (you'd retrofit a spine onto more drift). **Unanswered → emit both branches, never guess.** |
264296
| Schema owned by another team (DBA-gated) | migrate pillar restricted; model read-only ("metadata follows the schema"); flag the org constraint |
265297
| Deep hand-tuned ORM investment | churn warning, not a disqualifier: the plan must reproduce those mappings (`@column`/`@table`/`@dbColumnType`) and price it |
266298
| Team rejects generated code in the repo | flag; regen-every-build works but `verify --codegen` semantics differ — call the tradeoff |
@@ -353,6 +385,12 @@ MetaObjects at runtime (local-first) but adopting means owning a codegen step; m
353385
authoring debt is real — price the wave-0 reconciliation; early `verify --db` runs will
354386
surface legacy oddities — triage as findings, not noise.
355387

388+
**State this limit explicitly in §R7 (M8):** *this assessment can read your code, not your
389+
roadmap.* It counts what exists; it cannot see whether the system will grow, and growth is
390+
what decides the size-based verdict. Where the trajectory answer was given, name who gave it;
391+
where it wasn't, say which branch you assumed. An assessment that quietly converts "small
392+
today" into "not worth it, ever" is exactly the false negative this section exists to prevent.
393+
356394
---
357395

358396
## Report contract — `fit-assessment.md`, sections in this order
@@ -480,6 +518,9 @@ Every prose prediction gets a claim. Ceiling statements (P5-b) MUST carry
480518

481519
## Final self-check before writing
482520

521+
0. **Trajectory (M8): did you ASK, or did you infer "won't grow" from a small repo?** A flat
522+
NOT-A-FIT is legal ONLY on a structural disqualifier. If the size row is doing the work and
523+
the trajectory answer is missing, you must show both branches — not a verdict.
483524
1. Disqualifier table worked row-by-row? (Invalid output otherwise.)
484525
2. Census reconciliation block present, with predicted `object.entity` anchored to live
485526
tables, not ORM classes?

0 commit comments

Comments
 (0)