@terpjs/spec 0.20.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/catalog/backend/forwarded_filters_are_declared.json +27 -0
- package/corpus/backend/forwarded_filters_are_declared/compliant-01/modules/notes/router.py +5 -0
- package/corpus/backend/forwarded_filters_are_declared/compliant-01/modules/notes/service.py +9 -0
- package/corpus/backend/forwarded_filters_are_declared/compliant-02/modules/notes/router.py +5 -0
- package/corpus/backend/forwarded_filters_are_declared/violation-01/modules/notes/router.py +7 -0
- package/corpus/backend/forwarded_filters_are_declared/violation-01/modules/notes/service.py +9 -0
- package/package.json +1 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.21.1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "backend/forwarded_filters_are_declared",
|
|
3
|
+
"surface": "backend",
|
|
4
|
+
"title": "Every filter name a read endpoint forwards must be a declared filter",
|
|
5
|
+
"intent": "An endpoint that narrows a read forwards its optional query parameters unchanged, so a filter name that matches no declaration carries no value on any request that omits that parameter. The narrowing appears to be applied while the read stays unnarrowed, and no test that omits the parameter can observe the difference. Each forwarded filter name must correspond to a filter the read layer declares, so a name that no declaration backs is rejected on the source rather than on the one request that happens to supply a value for it.",
|
|
6
|
+
"layer": "static-portable",
|
|
7
|
+
"enforcement": [
|
|
8
|
+
{
|
|
9
|
+
"kind": "build-time",
|
|
10
|
+
"tool": "terp.arch",
|
|
11
|
+
"ref": "check_forwarded_filters_are_declared"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"kind": "runtime",
|
|
15
|
+
"tool": "terp.core",
|
|
16
|
+
"ref": "resolve_filters"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"reference": "A literal filter name forwarded from an endpoint that matches no declared filter is flagged at that name, and the message lists the declared names so a misspelling is visible against its intended target. Names that are not statically knowable — a filter mapping built elsewhere, or a computed name — are not judged, because a guess there would reject correct code.",
|
|
20
|
+
"opt_out": "# arch-allow-forwarded-filters-are-declared: <reason>",
|
|
21
|
+
"runtime": {
|
|
22
|
+
"applicability": "required",
|
|
23
|
+
"rationale": "The read layer resolves each forwarded name against the declarations while serving the request, and rejects an undeclared name before the read is built, so the invariant is observable and enforced fail-closed at runtime. The name is resolved before an absent value is discarded — checking the value first would leave an undeclared name both unreachable and unreported for as long as callers omit it, which is the defect this rule exists for. The build-time check is the earlier half: it holds for endpoints no request has exercised."
|
|
24
|
+
},
|
|
25
|
+
"guide_topic": "service",
|
|
26
|
+
"corpus": true
|
|
27
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# A filter mapping built elsewhere, and a computed name, are not statically
|
|
2
|
+
# knowable. Neither is judged: a guess there would reject correct code.
|
|
3
|
+
def list_notes(session, chosen, prepared):
|
|
4
|
+
service.list(session, filters=prepared)
|
|
5
|
+
return service.list(session, filters={chosen: 1})
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# "created_form" matches no declared filter, so it never narrows the read — and
|
|
2
|
+
# stays silent for every request that omits the parameter.
|
|
3
|
+
def list_notes(session, author_id=None, created_from=None):
|
|
4
|
+
return service.list(
|
|
5
|
+
session,
|
|
6
|
+
filters={"author_id": author_id, "created_form": created_from},
|
|
7
|
+
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terpjs/spec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"description": "The Terp Standard — stack-neutral rule catalog, violation corpus, finding format, and refused-surface declaration (ADRs 0080/0081; packaged per ADR 0082, published per ADR 0086). Data only: consumers resolve the spec root via require.resolve('@terpjs/spec/package.json').",
|
|
5
5
|
"files": [
|
|
6
6
|
"VERSION",
|