Spaces:
Sleeping
Sleeping
P0-R3 Research Design manual authority fix
#137
by GuXiaopeng - opened
- app.py +11 -18
- core/advanced_method_registry.py +8 -11
app.py
CHANGED
|
@@ -1517,11 +1517,10 @@ def render_workspace_controls(user):
|
|
| 1517 |
}
|
| 1518 |
method_signature = ""
|
| 1519 |
else:
|
| 1520 |
-
#
|
| 1521 |
-
#
|
| 1522 |
-
#
|
| 1523 |
-
# the
|
| 1524 |
-
# or blocking on an unsupported method family.
|
| 1525 |
auto_preflight, method_signature = _current_method_preflight(confirmed_method_family="")
|
| 1526 |
auto_family = str(auto_preflight.get("method_family") or "qualitative").strip().casefold()
|
| 1527 |
if auto_family not in METHOD_FAMILIES:
|
|
@@ -1531,16 +1530,14 @@ def render_workspace_controls(user):
|
|
| 1531 |
stored = str(st.session_state.get("sp_method_confirmation") or "").strip().casefold()
|
| 1532 |
stored_sig = str(st.session_state.get("sp_method_confirmation_signature") or "").strip()
|
| 1533 |
selected_default = (
|
| 1534 |
-
auto_family
|
| 1535 |
-
if specialized_redirect
|
| 1536 |
-
else (stored if stored_sig == method_signature and stored in METHOD_FAMILIES else auto_family)
|
| 1537 |
)
|
| 1538 |
|
| 1539 |
# A changed Title/Keywords signature invalidates a previous manual
|
| 1540 |
-
# override.
|
| 1541 |
-
#
|
| 1542 |
selector_sig = str(st.session_state.get("sp_method_selector_signature") or "").strip()
|
| 1543 |
-
if selector_sig != method_signature
|
| 1544 |
st.session_state["sp_method_confirmation"] = ""
|
| 1545 |
st.session_state["sp_method_confirmation_signature"] = ""
|
| 1546 |
st.session_state["sp_method_selector"] = auto_family
|
|
@@ -1555,14 +1552,10 @@ def render_workspace_controls(user):
|
|
| 1555 |
index=list(METHOD_FAMILIES).index(selected_default),
|
| 1556 |
format_func=lambda family: tr(lang_code, f"method_{family}"),
|
| 1557 |
key="sp_method_selector",
|
| 1558 |
-
disabled=active
|
| 1559 |
)
|
| 1560 |
selected = str(selected or auto_family).strip().casefold()
|
| 1561 |
-
if
|
| 1562 |
-
selected = "qualitative"
|
| 1563 |
-
st.session_state["sp_method_confirmation"] = ""
|
| 1564 |
-
st.session_state["sp_method_confirmation_signature"] = ""
|
| 1565 |
-
elif selected != auto_family:
|
| 1566 |
st.session_state["sp_method_confirmation"] = selected
|
| 1567 |
st.session_state["sp_method_confirmation_signature"] = method_signature
|
| 1568 |
else:
|
|
@@ -1582,7 +1575,7 @@ def render_workspace_controls(user):
|
|
| 1582 |
|
| 1583 |
block_reason = str(preflight.get("block_reason") or "")
|
| 1584 |
specialized_redirect = bool((preflight.get("resolution") or {}).get("specialized_method_detected"))
|
| 1585 |
-
if specialized_redirect and not active:
|
| 1586 |
st.warning(tr(lang_code, "specialized_method_redirect"))
|
| 1587 |
elif block_reason:
|
| 1588 |
st.warning(tr(lang_code, "method_resolution_invalid"))
|
|
|
|
| 1517 |
}
|
| 1518 |
method_signature = ""
|
| 1519 |
else:
|
| 1520 |
+
# SmartPaper intentionally supports only two reader-visible research
|
| 1521 |
+
# designs. No cue defaults to qualitative. Specialized-method cues remain
|
| 1522 |
+
# advisory-only for automatic detection; an explicit user selection
|
| 1523 |
+
# between the two supported designs is authoritative for this topic.
|
|
|
|
| 1524 |
auto_preflight, method_signature = _current_method_preflight(confirmed_method_family="")
|
| 1525 |
auto_family = str(auto_preflight.get("method_family") or "qualitative").strip().casefold()
|
| 1526 |
if auto_family not in METHOD_FAMILIES:
|
|
|
|
| 1530 |
stored = str(st.session_state.get("sp_method_confirmation") or "").strip().casefold()
|
| 1531 |
stored_sig = str(st.session_state.get("sp_method_confirmation_signature") or "").strip()
|
| 1532 |
selected_default = (
|
| 1533 |
+
stored if stored_sig == method_signature and stored in METHOD_FAMILIES else auto_family
|
|
|
|
|
|
|
| 1534 |
)
|
| 1535 |
|
| 1536 |
# A changed Title/Keywords signature invalidates a previous manual
|
| 1537 |
+
# override. For the same signature, the user's explicit selection remains
|
| 1538 |
+
# authoritative even when automatic detection found a specialized cue.
|
| 1539 |
selector_sig = str(st.session_state.get("sp_method_selector_signature") or "").strip()
|
| 1540 |
+
if selector_sig != method_signature:
|
| 1541 |
st.session_state["sp_method_confirmation"] = ""
|
| 1542 |
st.session_state["sp_method_confirmation_signature"] = ""
|
| 1543 |
st.session_state["sp_method_selector"] = auto_family
|
|
|
|
| 1552 |
index=list(METHOD_FAMILIES).index(selected_default),
|
| 1553 |
format_func=lambda family: tr(lang_code, f"method_{family}"),
|
| 1554 |
key="sp_method_selector",
|
| 1555 |
+
disabled=active,
|
| 1556 |
)
|
| 1557 |
selected = str(selected or auto_family).strip().casefold()
|
| 1558 |
+
if selected != auto_family:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1559 |
st.session_state["sp_method_confirmation"] = selected
|
| 1560 |
st.session_state["sp_method_confirmation_signature"] = method_signature
|
| 1561 |
else:
|
|
|
|
| 1575 |
|
| 1576 |
block_reason = str(preflight.get("block_reason") or "")
|
| 1577 |
specialized_redirect = bool((preflight.get("resolution") or {}).get("specialized_method_detected"))
|
| 1578 |
+
if specialized_redirect and not active and method_family == "qualitative":
|
| 1579 |
st.warning(tr(lang_code, "specialized_method_redirect"))
|
| 1580 |
elif block_reason:
|
| 1581 |
st.warning(tr(lang_code, "method_resolution_invalid"))
|
core/advanced_method_registry.py
CHANGED
|
@@ -5,8 +5,9 @@ U1-R2C intentionally limits production research design to two supported paths:
|
|
| 5 |
qualitative research and survey-based quantitative research. Specialized cues
|
| 6 |
such as fsQCA, panel data/econometrics, meta-analysis, and bibliometric/review
|
| 7 |
methods are detected only to provide a reader-facing scope notice; they are not
|
| 8 |
-
exposed as selectable method families
|
| 9 |
-
framework
|
|
|
|
| 10 |
|
| 11 |
This module never selects providers/models and never rewrites Title/Keywords.
|
| 12 |
"""
|
|
@@ -16,7 +17,7 @@ import os
|
|
| 16 |
import re
|
| 17 |
from typing import Any, Iterable
|
| 18 |
|
| 19 |
-
METHOD_RESOLVER_VERSION = "smartpaper-auto-method-resolver-
|
| 20 |
METHOD_CAPABILITY_REGISTRY_VERSION = "smartpaper-method-capability-registry-v3"
|
| 21 |
|
| 22 |
# Reader-visible / task-owning method families. Order is intentional:
|
|
@@ -252,16 +253,15 @@ def resolve_generation_preflight(
|
|
| 252 |
"""Resolve the two supported designs before any task/quota creation.
|
| 253 |
|
| 254 |
Manual adjustment is available only between qualitative and survey-based
|
| 255 |
-
quantitative research.
|
| 256 |
-
|
| 257 |
-
|
| 258 |
"""
|
| 259 |
resolution = resolve_method_family(title, keywords, materials=materials)
|
| 260 |
family = str(resolution.get("method_family") or "qualitative").strip().casefold()
|
| 261 |
|
| 262 |
confirmed = str(confirmed_method_family or "").strip().casefold()
|
| 263 |
-
|
| 264 |
-
if not specialized and confirmed in METHOD_FAMILIES and confirmed != family:
|
| 265 |
family = confirmed
|
| 266 |
capability = method_capability(family)
|
| 267 |
resolution = dict(resolution)
|
|
@@ -272,9 +272,6 @@ def resolve_generation_preflight(
|
|
| 272 |
"capability": capability,
|
| 273 |
"reason_codes": list(resolution.get("reason_codes") or []) + ["user_override_method_family"],
|
| 274 |
})
|
| 275 |
-
elif specialized:
|
| 276 |
-
resolution = dict(resolution)
|
| 277 |
-
resolution["manual_override_locked"] = True
|
| 278 |
|
| 279 |
capability = method_capability(family)
|
| 280 |
lane = str(capability.get("legacy_policy_lane") or "").strip().casefold() or None
|
|
|
|
| 5 |
qualitative research and survey-based quantitative research. Specialized cues
|
| 6 |
such as fsQCA, panel data/econometrics, meta-analysis, and bibliometric/review
|
| 7 |
methods are detected only to provide a reader-facing scope notice; they are not
|
| 8 |
+
exposed as selectable method families. Automatic detection falls back to the
|
| 9 |
+
qualitative framework, while an explicit user selection between the two supported
|
| 10 |
+
designs remains authoritative for the current Title + Keywords signature.
|
| 11 |
|
| 12 |
This module never selects providers/models and never rewrites Title/Keywords.
|
| 13 |
"""
|
|
|
|
| 17 |
import re
|
| 18 |
from typing import Any, Iterable
|
| 19 |
|
| 20 |
+
METHOD_RESOLVER_VERSION = "smartpaper-auto-method-resolver-v5"
|
| 21 |
METHOD_CAPABILITY_REGISTRY_VERSION = "smartpaper-method-capability-registry-v3"
|
| 22 |
|
| 23 |
# Reader-visible / task-owning method families. Order is intentional:
|
|
|
|
| 253 |
"""Resolve the two supported designs before any task/quota creation.
|
| 254 |
|
| 255 |
Manual adjustment is available only between qualitative and survey-based
|
| 256 |
+
quantitative research. Automatic detection may map specialized-method cues
|
| 257 |
+
to the qualitative fallback, but an explicit user selection between the two
|
| 258 |
+
supported production designs is authoritative for the current topic.
|
| 259 |
"""
|
| 260 |
resolution = resolve_method_family(title, keywords, materials=materials)
|
| 261 |
family = str(resolution.get("method_family") or "qualitative").strip().casefold()
|
| 262 |
|
| 263 |
confirmed = str(confirmed_method_family or "").strip().casefold()
|
| 264 |
+
if confirmed in METHOD_FAMILIES and confirmed != family:
|
|
|
|
| 265 |
family = confirmed
|
| 266 |
capability = method_capability(family)
|
| 267 |
resolution = dict(resolution)
|
|
|
|
| 272 |
"capability": capability,
|
| 273 |
"reason_codes": list(resolution.get("reason_codes") or []) + ["user_override_method_family"],
|
| 274 |
})
|
|
|
|
|
|
|
|
|
|
| 275 |
|
| 276 |
capability = method_capability(family)
|
| 277 |
lane = str(capability.get("legacy_policy_lane") or "").strip().casefold() or None
|