fix(engineering): resolve 3 bugs in senior-backend + senior-frontend decision engines

Addresses claude[bot] code review findings on PR #718.

1. backend_decision_engine.py: scoped language-preference match
   Previous code serialized the entire profile dict to JSON and ran a
   substring search, so --language-preference=go false-matched against
   "django", "mongo", etc. New approach tokenizes profile_name +
   stack.language + stack.runtime on '-' and checks exact membership.

   Verified:
     - language=go    → matches go-or-rust-microservice only
     - language=python → matches django-monolith + fastapi-python only
     - language=typescript → matches node-express only

2. frontend_decision_engine.py: removed dead pass-block kill check
   `if team_size in 4..10 and read_write_ratio >= 50: pass` was a no-op
   with an unclear intent comment. Removed.

3. frontend_decision_engine.py: wired up unused inp_target_ms field
   The field was declared on Inputs, exposed via --inp-target-ms, and
   threaded through main() but never consulted by any kill criterion.
   Added a kill check that mirrors the existing LCP one:
     "mobile-4g primary with INP target Xms: tighten to < 200ms"
   (Web Vitals 'good' threshold for INP is 200ms; 'poor' is 500ms.)

Verification:
- backend_decision_engine.py --sample → exit 0
- frontend_decision_engine.py --sample → exit 0
- fullstack_decision_engine.py --sample → exit 0 (untouched)
This commit is contained in:
Claude 2026-05-21 12:56:19 +00:00
parent 2bc328f2fc
commit 472f0ace5c
No known key found for this signature in database
2 changed files with 23 additions and 12 deletions

View file

@ -153,15 +153,24 @@ def score_profile(profile: dict[str, Any], inputs: Inputs) -> Match:
inputs.needs_admin_panel == c["admin_panel_needed"],
weight=1.0,
)
# Language preference soft-match
stack_keys = list(profile.keys())
stack_lang_hits = sum(
1 for k in stack_keys
if k.startswith("stack") and inputs.language_preference.lower() in json.dumps(profile.get(k, {})).lower()
)
base_stack = profile.get("stack", {})
if inputs.language_preference and (stack_lang_hits or inputs.language_preference.lower() in json.dumps(base_stack).lower()):
check(f"stack-language matches '{inputs.language_preference}'", True, weight=1.0)
# Language preference — match only against fields that explicitly name a language:
# profile_name, stack.language, stack.runtime. The previous substring search over
# the entire serialized profile false-matched e.g. "go" against "django"/"mongo".
if inputs.language_preference:
lang = inputs.language_preference.lower()
stack = profile.get("stack", {})
language_fields = [
name.lower(),
str(stack.get("language", "")).lower(),
str(stack.get("runtime", "")).lower(),
]
# Token-level match: split on '-' and check exact membership so "go" doesn't
# match "mongo" but still matches "go-or-rust-microservice".
tokens: set[str] = set()
for field in language_fields:
tokens.update(field.replace("_", "-").split("-"))
if lang in tokens:
check(f"stack-language matches '{inputs.language_preference}'", True, weight=1.0)
score = w_matched / w_total if w_total > 0 else 0.0
return Match(

View file

@ -58,9 +58,11 @@ class Inputs:
f"mobile-4g primary with LCP target {self.lcp_target_ms}ms: "
"target is too loose for the device class. Tighten to < 2500ms (Web Vitals 'good')."
)
if self.team_size >= 4 and self.team_size <= 10 and self.read_write_ratio >= 50:
# Hint: marketing-site shape but with a real team
pass
if self.primary_device == "mobile-4g" and self.inp_target_ms > 300:
kills.append(
f"mobile-4g primary with INP target {self.inp_target_ms}ms: "
"target is too loose for the device class. Tighten to < 200ms (Web Vitals 'good')."
)
if self.team_size < 1:
kills.append("team_size < 1 makes no sense.")
return kills