@bongos/core 1.19.454 → 1.19.456
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/.bongos-core.json +116 -51
- package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +1 -0
- package/docs/copy-inventory.md +231 -228
- package/docs/copy-registry.json +352 -312
- package/docs/module-api-changelog.md +4 -0
- package/modules/discord/db.js +0 -3
- package/modules/discord/discord-bot.js +8 -1
- package/modules/discord/discord-bugs.js +133 -74
- package/modules/discord/module.json +1 -1
- package/modules/hall-ui/public/atlas.css +41 -32
- package/modules/hall-ui/public/atlas.html +8 -0
- package/modules/hall-ui/public/atlas.states.json +60 -0
- package/modules/hall-ui/public/collab.css +2 -2
- package/modules/hall-ui/public/collab.html +7 -1
- package/modules/hall-ui/public/collab.states.json +60 -0
- package/modules/hall-ui/public/copy-desk.css +21 -16
- package/modules/hall-ui/public/copy-desk.html +9 -1
- package/modules/hall-ui/public/copy-desk.states.json +59 -0
- package/modules/hall-ui/public/drachmae.html +38 -5
- package/modules/hall-ui/public/drachmae.js +20 -2
- package/modules/hall-ui/public/drachmae.states.json +64 -0
- package/modules/hall-ui/public/gate.css +20 -25
- package/modules/hall-ui/public/gate.html +9 -1
- package/modules/hall-ui/public/gate.states.json +60 -0
- package/modules/hall-ui/public/goals-lib.js +22 -5
- package/modules/hall-ui/public/goals-render.js +27 -5
- package/modules/hall-ui/public/goals.css +141 -60
- package/modules/hall-ui/public/goals.html +8 -1
- package/modules/hall-ui/public/goals.states.json +74 -0
- package/modules/hall-ui/public/government.css +35 -36
- package/modules/hall-ui/public/government.html +9 -1
- package/modules/hall-ui/public/government.states.json +59 -0
- package/modules/hall-ui/public/harbor.css +23 -26
- package/modules/hall-ui/public/harbor.html +9 -1
- package/modules/hall-ui/public/harbor.states.json +59 -0
- package/modules/hall-ui/public/modules.css +22 -21
- package/modules/hall-ui/public/modules.html +9 -1
- package/modules/hall-ui/public/modules.states.json +73 -0
- package/modules/hall-ui/public/people.html +7 -1
- package/modules/hall-ui/public/people.states.json +59 -0
- package/modules/hall-ui/public/scouting.html +7 -1
- package/modules/hall-ui/public/scouting.states.json +54 -0
- package/modules/hall-ui/public/sessions.css +1 -1
- package/modules/hall-ui/public/sessions.html +9 -1
- package/modules/hall-ui/public/sessions.states.json +58 -0
- package/modules/hall-ui/public/style.css +125 -5
- package/modules/hall-ui/public/watch.css +36 -39
- package/modules/hall-ui/public/watch.html +9 -1
- package/modules/hall-ui/public/watch.states.json +60 -0
- package/modules/lifecycle/goal-suggest.js +70 -2
- package/modules/lifecycle/lifecycle.js +7 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/discord_bugs.mjs +110 -31
- package/tests/filing_abuse_matrix.mjs +59 -20
- package/tests/goal_subtitle.mjs +14 -8
- package/tests/goal_suggest.mjs +107 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "Collab — the two-sided ask board. ASKED OF YOU comes first because it is the half where someone is waiting, and the empty state of that half is the page's most common render. Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
|
|
3
|
+
"page": "/builders/collab",
|
|
4
|
+
"surface": "hall-ui",
|
|
5
|
+
"stub": {
|
|
6
|
+
"prefix": "/builders/"
|
|
7
|
+
},
|
|
8
|
+
"modeQuery": false,
|
|
9
|
+
"_feeds": "The kit's own stub carries no feed for this page, so against it the page renders its EMPTY and SKELETON states — which is the point: those are states the floors must hold in. Against the hall-preview harness the same states render populated. Every declared 404 below is a fixture the harness does not carry, named rather than hidden.",
|
|
10
|
+
"ignoreRequests": [
|
|
11
|
+
"/api/(gds|bongos)/me$",
|
|
12
|
+
"/api/(gds|bongos)/me/",
|
|
13
|
+
"/api/(gds|bongos)/goals",
|
|
14
|
+
"/api/(gds|bongos)/inbox/",
|
|
15
|
+
"/api/(gds|bongos)/versions",
|
|
16
|
+
"/api/(gds|bongos)/collab",
|
|
17
|
+
"/api/(gds|bongos)/connections",
|
|
18
|
+
"/api/(gds|bongos)/v1/help-requests"
|
|
19
|
+
],
|
|
20
|
+
"ignoreConsole": [
|
|
21
|
+
"/api/(gds|bongos)/",
|
|
22
|
+
"\\b401\\b",
|
|
23
|
+
"\\b403\\b",
|
|
24
|
+
"\\b404\\b",
|
|
25
|
+
"\\b501\\b",
|
|
26
|
+
"Unauthorized",
|
|
27
|
+
"Forbidden",
|
|
28
|
+
"Not Found",
|
|
29
|
+
"Not Implemented",
|
|
30
|
+
"load failed"
|
|
31
|
+
],
|
|
32
|
+
"states": {
|
|
33
|
+
"board": {
|
|
34
|
+
"auth": true,
|
|
35
|
+
"actions": [
|
|
36
|
+
[
|
|
37
|
+
"wait",
|
|
38
|
+
700
|
|
39
|
+
]
|
|
40
|
+
],
|
|
41
|
+
"expect": {
|
|
42
|
+
"visible": [
|
|
43
|
+
"#cb-for-me"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"out": {
|
|
48
|
+
"auth": false
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"reducedMotion": {
|
|
52
|
+
"auth": true,
|
|
53
|
+
"actions": [
|
|
54
|
+
[
|
|
55
|
+
"wait",
|
|
56
|
+
600
|
|
57
|
+
]
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -17,18 +17,20 @@
|
|
|
17
17
|
flex-direction: column;
|
|
18
18
|
gap: 0.15rem;
|
|
19
19
|
padding: 0.75rem 0.9rem;
|
|
20
|
-
border:
|
|
21
|
-
border-radius:
|
|
22
|
-
background: var(--
|
|
20
|
+
border: var(--line) solid var(--rule-soft);
|
|
21
|
+
border-radius: var(--radius-sm);
|
|
22
|
+
background: var(--glass);
|
|
23
23
|
}
|
|
24
24
|
.cd-stat__n { font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
|
|
25
25
|
.cd-stat__l { font-size: 0.8rem; opacity: 0.7; }
|
|
26
26
|
|
|
27
27
|
.cd-note { font-size: 0.85rem; opacity: 0.75; line-height: 1.5; }
|
|
28
|
+
/* 4px, not --radius-sm: a 10px radius on a 16px-tall inline span reads as a
|
|
29
|
+
pill, and the tier has no smaller token. Deliberate, not missed. */
|
|
28
30
|
.cd-note code {
|
|
29
31
|
padding: 0.05rem 0.3rem;
|
|
30
32
|
border-radius: 0.25rem;
|
|
31
|
-
background: var(--
|
|
33
|
+
background: var(--glass);
|
|
32
34
|
font-size: 0.95em;
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -40,8 +42,8 @@
|
|
|
40
42
|
.cd-dialog__input,
|
|
41
43
|
.cd-dialog__text {
|
|
42
44
|
padding: 0.4rem 0.6rem;
|
|
43
|
-
border:
|
|
44
|
-
border-radius:
|
|
45
|
+
border: var(--line) solid var(--rule-soft);
|
|
46
|
+
border-radius: var(--radius-sm);
|
|
45
47
|
background: var(--bg-deep);
|
|
46
48
|
color: inherit;
|
|
47
49
|
font: inherit;
|
|
@@ -56,9 +58,9 @@
|
|
|
56
58
|
|
|
57
59
|
.cd-card {
|
|
58
60
|
padding: 0.85rem 1rem;
|
|
59
|
-
border:
|
|
60
|
-
border-radius:
|
|
61
|
-
background: var(--
|
|
61
|
+
border: var(--line) solid var(--rule-soft);
|
|
62
|
+
border-radius: var(--radius-sm);
|
|
63
|
+
background: var(--glass);
|
|
62
64
|
}
|
|
63
65
|
.cd-card--slim { padding: 0.6rem 0.8rem; }
|
|
64
66
|
.cd-card__head { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-bottom: 0.4rem; }
|
|
@@ -70,23 +72,23 @@
|
|
|
70
72
|
leading and trailing space in a string is often exactly what is wrong. */
|
|
71
73
|
.cd-quote {
|
|
72
74
|
quotes: '"' '"';
|
|
73
|
-
font-family:
|
|
75
|
+
font-family: var(--font-mono);
|
|
74
76
|
font-size: 0.9em;
|
|
75
77
|
white-space: pre-wrap;
|
|
76
78
|
word-break: break-word;
|
|
77
79
|
}
|
|
78
|
-
.cd-where { font-size: 0.8rem; opacity: 0.6; font-family:
|
|
80
|
+
.cd-where { font-size: 0.8rem; opacity: 0.6; font-family: var(--font-mono); }
|
|
79
81
|
.cd-byline { font-size: 0.8rem; opacity: 0.65; margin-left: auto; }
|
|
80
82
|
.cd-reason { margin: 0.3rem 0 0; line-height: 1.55; }
|
|
81
83
|
.cd-snapshot-label { font-size: 0.8rem; opacity: 0.6; }
|
|
82
84
|
.cd-closed { margin: 0.5rem 0 0; font-size: 0.85rem; opacity: 0.8; line-height: 1.5; }
|
|
83
|
-
.cd-places { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.8rem; opacity: 0.65; font-family:
|
|
85
|
+
.cd-places { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.8rem; opacity: 0.65; font-family: var(--font-mono); }
|
|
84
86
|
|
|
85
87
|
.cd-tag {
|
|
86
88
|
display: inline-block;
|
|
87
89
|
padding: 0.1rem 0.45rem;
|
|
88
|
-
border:
|
|
89
|
-
border-radius:
|
|
90
|
+
border: var(--line) solid var(--rule);
|
|
91
|
+
border-radius: var(--radius-pill);
|
|
90
92
|
font-size: 0.72rem;
|
|
91
93
|
letter-spacing: 0.02em;
|
|
92
94
|
opacity: 0.85;
|
|
@@ -103,11 +105,14 @@
|
|
|
103
105
|
.cd-dialog {
|
|
104
106
|
width: min(34rem, 92vw);
|
|
105
107
|
padding: 1.25rem;
|
|
106
|
-
border:
|
|
107
|
-
border-radius:
|
|
108
|
+
border: var(--line) solid var(--rule);
|
|
109
|
+
border-radius: var(--radius);
|
|
108
110
|
background: var(--bg-card);
|
|
109
111
|
color: inherit;
|
|
110
112
|
}
|
|
113
|
+
/* The one literal this sheet keeps. Pure black with alpha used as a SCRIM is
|
|
114
|
+
the single exception the Fifteen Rule names, and a backdrop cannot take a
|
|
115
|
+
ground token: it has to darken whatever is behind it in either mode. */
|
|
111
116
|
.cd-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
|
|
112
117
|
.cd-dialog__h { margin: 0 0 0.5rem; font-size: 1.1rem; }
|
|
113
118
|
.cd-dialog__target { margin: 0 0 0.9rem; line-height: 1.5; }
|
|
@@ -19,7 +19,15 @@
|
|
|
19
19
|
<div class="app-body">
|
|
20
20
|
<header class="app-topbar" id="app-topbar"></header>
|
|
21
21
|
<div class="app-content">
|
|
22
|
-
|
|
22
|
+
<!-- task 1003307: the board page head. Copy desk shipped with NO <h1> at all
|
|
23
|
+
(one-header-main-h1 measured 0 on every render), so the re-skin
|
|
24
|
+
carries the structural fix rather than porting the hole. The heading
|
|
25
|
+
is the LABEL voice, not a display line: on a working surface the
|
|
26
|
+
page's own name is the least interesting thing on it. -->
|
|
27
|
+
<div class="page-head page-head--board">
|
|
28
|
+
<h1 class="page-head__h">Copy desk</h1>
|
|
29
|
+
<p class="page-head__sub" id="cd-sub">Loading the copy desk…</p>
|
|
30
|
+
</div>
|
|
23
31
|
|
|
24
32
|
<main id="hall-main">
|
|
25
33
|
<!-- The counts. Deliberately four numbers and not a dashboard: open work,
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "Copy desk — the one-voice review queue. Its confirm dialog is a real <dialog>, so its ::backdrop is the sheet's single sanctioned literal (black with alpha as a scrim). Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
|
|
3
|
+
"page": "/builders/copy-desk",
|
|
4
|
+
"surface": "hall-ui",
|
|
5
|
+
"stub": {
|
|
6
|
+
"prefix": "/builders/"
|
|
7
|
+
},
|
|
8
|
+
"modeQuery": false,
|
|
9
|
+
"_feeds": "The kit's own stub carries no feed for this page, so against it the page renders its EMPTY and SKELETON states — which is the point: those are states the floors must hold in. Against the hall-preview harness the same states render populated. Every declared 404 below is a fixture the harness does not carry, named rather than hidden.",
|
|
10
|
+
"ignoreRequests": [
|
|
11
|
+
"/api/(gds|bongos)/me$",
|
|
12
|
+
"/api/(gds|bongos)/me/",
|
|
13
|
+
"/api/(gds|bongos)/goals",
|
|
14
|
+
"/api/(gds|bongos)/inbox/",
|
|
15
|
+
"/api/(gds|bongos)/versions",
|
|
16
|
+
"/api/(gds|bongos)/copy",
|
|
17
|
+
"/api/(gds|bongos)/security/"
|
|
18
|
+
],
|
|
19
|
+
"ignoreConsole": [
|
|
20
|
+
"/api/(gds|bongos)/",
|
|
21
|
+
"\\b401\\b",
|
|
22
|
+
"\\b403\\b",
|
|
23
|
+
"\\b404\\b",
|
|
24
|
+
"\\b501\\b",
|
|
25
|
+
"Unauthorized",
|
|
26
|
+
"Forbidden",
|
|
27
|
+
"Not Found",
|
|
28
|
+
"Not Implemented",
|
|
29
|
+
"load failed"
|
|
30
|
+
],
|
|
31
|
+
"states": {
|
|
32
|
+
"queue": {
|
|
33
|
+
"auth": true,
|
|
34
|
+
"actions": [
|
|
35
|
+
[
|
|
36
|
+
"wait",
|
|
37
|
+
700
|
|
38
|
+
]
|
|
39
|
+
],
|
|
40
|
+
"expect": {
|
|
41
|
+
"visible": [
|
|
42
|
+
"#cd-summary-scroll"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"out": {
|
|
47
|
+
"auth": false
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"reducedMotion": {
|
|
51
|
+
"auth": true,
|
|
52
|
+
"actions": [
|
|
53
|
+
[
|
|
54
|
+
"wait",
|
|
55
|
+
600
|
|
56
|
+
]
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -9,9 +9,15 @@
|
|
|
9
9
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
11
|
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
12
|
+
<!-- task 1003307: the reading-room archetype's own sheet. drachmae reuses the
|
|
13
|
+
primer's layout and loaded primer.css for it, but never room.css — so it
|
|
14
|
+
had the room's DOM and none of the room's world: no reading measure, no
|
|
15
|
+
prose-link 24px floor, no table wrapper. Loading it is the fix; the order
|
|
16
|
+
matches primer.html (room first, the page's own sheet on top). -->
|
|
17
|
+
<link rel="stylesheet" href="/builders/room.css">
|
|
12
18
|
<link rel="stylesheet" href="/builders/primer.css?v=2026-07-02-shell1">
|
|
13
19
|
</head>
|
|
14
|
-
<body class="primer-body" data-page="drachmae" data-page-title="Drachmae & karma">
|
|
20
|
+
<body class="room primer-body" data-page="drachmae" data-page-title="Drachmae & karma">
|
|
15
21
|
|
|
16
22
|
<!-- Reading-progress bar — fills as the reader scrolls through the article. -->
|
|
17
23
|
<div class="primer-progress" aria-hidden="true"><div class="primer-progress__bar" id="primer-progress-bar"></div></div>
|
|
@@ -23,7 +29,13 @@
|
|
|
23
29
|
<header class="app-topbar" id="app-topbar"></header>
|
|
24
30
|
<div class="app-content">
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
<!-- task 1003307: the reading-room head. drachmae shares the primer's
|
|
33
|
+
.primer-layout and is read as a document, so it takes .page-head--room
|
|
34
|
+
(task 1003306's archetype) rather than the board's label voice — and
|
|
35
|
+
it gets the <h1> it never had. -->
|
|
36
|
+
<div class="page-head page-head--room">
|
|
37
|
+
<p class="page-head__eyebrow">Docs</p>
|
|
38
|
+
<h1 class="page-head__h">Drachmae & karma</h1>
|
|
27
39
|
<p class="page-head__sub">How you get paid, and how you earn trust — the reward model in plain language. About a five-minute read.</p>
|
|
28
40
|
</div>
|
|
29
41
|
|
|
@@ -45,9 +57,30 @@
|
|
|
45
57
|
</aside>
|
|
46
58
|
|
|
47
59
|
<!-- Article column — markdown rendered here. -->
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
<!-- The room's loading shape: skeleton lines in the article's own
|
|
61
|
+
measure, not a sentence. (.primer-loading, which used to sit in the
|
|
62
|
+
article, is defined in no stylesheet and rendered unstyled.) -->
|
|
63
|
+
<div class="primer-skeleton scroll" id="primer-skeleton" aria-hidden="true">
|
|
64
|
+
<span class="primer-sk primer-skeleton__h"></span>
|
|
65
|
+
<div class="primer-skeleton__p">
|
|
66
|
+
<span class="primer-sk"></span>
|
|
67
|
+
<span class="primer-sk"></span>
|
|
68
|
+
<span class="primer-sk"></span>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="primer-skeleton__rule"></div>
|
|
71
|
+
<div class="primer-skeleton__p">
|
|
72
|
+
<span class="primer-sk"></span>
|
|
73
|
+
<span class="primer-sk"></span>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<article class="primer-article scroll" id="primer-article" aria-busy="true" hidden></article>
|
|
78
|
+
|
|
79
|
+
<div class="primer-note primer-note--error scroll" id="primer-error" hidden>
|
|
80
|
+
<p class="primer-note__label">The guide did not load</p>
|
|
81
|
+
<p class="primer-note__body">The markdown behind this page could not be fetched. Reload to try again, or read it in the repo.</p>
|
|
82
|
+
<p class="primer-note__acts"><a class="btn btn--ghost" href="/builders">Back to home</a></p>
|
|
83
|
+
</div>
|
|
51
84
|
|
|
52
85
|
</div>
|
|
53
86
|
</main>
|
|
@@ -146,9 +146,21 @@
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
// The three panels the article can resolve into (the primer's show(), which
|
|
150
|
+
// this page's DOM has mirrored since task 1472 and now finally matches).
|
|
151
|
+
function show(which) {
|
|
152
|
+
for (const [id, on] of [['#primer-skeleton', which === 'loading'],
|
|
153
|
+
['#primer-article', which === 'article'],
|
|
154
|
+
['#primer-error', which === 'error']]) {
|
|
155
|
+
const el = $(id);
|
|
156
|
+
if (el) el.hidden = !on;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
149
160
|
async function boot() {
|
|
150
161
|
const article = $('#primer-article');
|
|
151
162
|
if (!article || !window.OTBMdReader) return;
|
|
163
|
+
show('loading');
|
|
152
164
|
let md;
|
|
153
165
|
try {
|
|
154
166
|
const [mdRes] = await Promise.all([
|
|
@@ -159,8 +171,8 @@
|
|
|
159
171
|
md = await mdRes.text();
|
|
160
172
|
} catch (err) {
|
|
161
173
|
console.error('[drachmae] failed to load doc', err);
|
|
162
|
-
article.innerHTML = `<p class="primer-loading">Could not load the drachmae guide. <a href="/builders">Go back</a> and try again.</p>`;
|
|
163
174
|
article.removeAttribute('aria-busy');
|
|
175
|
+
show('error');
|
|
164
176
|
return;
|
|
165
177
|
}
|
|
166
178
|
const resolveLinkHref = window.OTBMdReader.makeResolveLinkHref({
|
|
@@ -169,9 +181,15 @@
|
|
|
169
181
|
getTreeBase: () => repoTreeBase,
|
|
170
182
|
diagramsHref: '/builders/diagrams',
|
|
171
183
|
});
|
|
172
|
-
const
|
|
184
|
+
const parsed = window.OTBMdReader.parseMarkdown(md, resolveLinkHref);
|
|
185
|
+
// The doc's leading "# …" is the same page name .page-head--room already
|
|
186
|
+
// renders. Two <h1>s fails one-header-main-h1, and the page head is the one
|
|
187
|
+
// that exists before the fetch and survives its failure (task 1003307).
|
|
188
|
+
const html = parsed.html.replace(/^\s*<h1\b[^>]*>[\s\S]*?<\/h1>\s*/, '');
|
|
189
|
+
const headings = parsed.headings.filter((h) => h.level > 1);
|
|
173
190
|
article.innerHTML = html;
|
|
174
191
|
article.removeAttribute('aria-busy');
|
|
192
|
+
show('article');
|
|
175
193
|
// Awaited before the TOC is built so the rate card gets a TOC entry and a
|
|
176
194
|
// scrollspy target; the article itself is already on screen by now.
|
|
177
195
|
const bountyHeading = await appendBountySection(article);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "Drachmae & karma — a READING ROOM, not a board: it shares the primer .primer-layout and takes .page-head--room. Public (no page gate), so the signed-out render is the one most readers get. Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
|
|
3
|
+
"page": "/builders/drachmae",
|
|
4
|
+
"surface": "hall-ui",
|
|
5
|
+
"stub": {
|
|
6
|
+
"prefix": "/builders/"
|
|
7
|
+
},
|
|
8
|
+
"modeQuery": false,
|
|
9
|
+
"_feeds": "The kit's own stub carries no feed for this page, so against it the page renders its EMPTY and SKELETON states — which is the point: those are states the floors must hold in. Against the hall-preview harness the same states render populated. Every declared 404 below is a fixture the harness does not carry, named rather than hidden.",
|
|
10
|
+
"ignoreRequests": [
|
|
11
|
+
"/api/(gds|bongos)/me$",
|
|
12
|
+
"/api/(gds|bongos)/me/",
|
|
13
|
+
"/api/(gds|bongos)/goals",
|
|
14
|
+
"/api/(gds|bongos)/inbox/",
|
|
15
|
+
"/api/(gds|bongos)/versions"
|
|
16
|
+
],
|
|
17
|
+
"ignoreConsole": [
|
|
18
|
+
"/api/(gds|bongos)/",
|
|
19
|
+
"\\b401\\b",
|
|
20
|
+
"\\b403\\b",
|
|
21
|
+
"\\b404\\b",
|
|
22
|
+
"\\b501\\b",
|
|
23
|
+
"Unauthorized",
|
|
24
|
+
"Forbidden",
|
|
25
|
+
"Not Found",
|
|
26
|
+
"Not Implemented",
|
|
27
|
+
"load failed"
|
|
28
|
+
],
|
|
29
|
+
"states": {
|
|
30
|
+
"read": {
|
|
31
|
+
"auth": true,
|
|
32
|
+
"actions": [
|
|
33
|
+
[
|
|
34
|
+
"wait",
|
|
35
|
+
600
|
|
36
|
+
]
|
|
37
|
+
],
|
|
38
|
+
"expect": {
|
|
39
|
+
"visible": [
|
|
40
|
+
"#primer-article",
|
|
41
|
+
"#primer-toc"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"out": {
|
|
46
|
+
"auth": false,
|
|
47
|
+
"actions": [
|
|
48
|
+
[
|
|
49
|
+
"wait",
|
|
50
|
+
600
|
|
51
|
+
]
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"reducedMotion": {
|
|
56
|
+
"auth": true,
|
|
57
|
+
"actions": [
|
|
58
|
+
[
|
|
59
|
+
"wait",
|
|
60
|
+
600
|
|
61
|
+
]
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
margin: 6px 0 22px;
|
|
14
14
|
}
|
|
15
15
|
.gate-stat {
|
|
16
|
-
border:
|
|
17
|
-
background: var(--
|
|
16
|
+
border: var(--line) solid var(--rule-soft); border-radius: var(--radius-sm);
|
|
17
|
+
background: var(--bg-card); padding: 12px 14px;
|
|
18
18
|
}
|
|
19
19
|
.gate-stat__label {
|
|
20
20
|
font-size: 11.5px; font-weight: 600;
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
.gate-list { display: flex; flex-direction: column; gap: 16px; }
|
|
29
29
|
|
|
30
30
|
.gate-crate {
|
|
31
|
-
border:
|
|
32
|
-
background: var(--
|
|
31
|
+
border: var(--line) solid var(--rule-soft); border-radius: var(--radius);
|
|
32
|
+
background: var(--bg-card); overflow: hidden;
|
|
33
33
|
}
|
|
34
34
|
/* Verdict band along the top, painted by the held-verdict. */
|
|
35
35
|
.gate-crate__seal { height: 4px; background-color: var(--danger); }
|
|
@@ -40,45 +40,40 @@
|
|
|
40
40
|
.gate-crate__title a { color: inherit; text-decoration: none; }
|
|
41
41
|
.gate-crate__title a:hover { text-decoration: underline; }
|
|
42
42
|
.gate-crate__meta { color: var(--ink-soft); font-size: 12.5px; }
|
|
43
|
-
.gate-crate__meta a { color: var(--accent-
|
|
43
|
+
.gate-crate__meta a { color: var(--accent-ink); }
|
|
44
44
|
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
border: 1px solid var(--border); color: var(--ink-soft); background: var(--surface-2);
|
|
50
|
-
}
|
|
51
|
-
.gate-pill--escalate { background: var(--danger-weak); border-color: color-mix(in srgb, var(--danger) 30%, transparent); color: var(--danger); }
|
|
52
|
-
.gate-pill--needs_trust { background: var(--warn-weak); border-color: color-mix(in srgb, var(--warn) 30%, transparent); color: var(--warn); }
|
|
53
|
-
.gate-pill--trusted { background: var(--info-weak); border-color: color-mix(in srgb, var(--info) 30%, transparent); color: var(--info); }
|
|
45
|
+
/* Base: the shell's .fact-pill (task 1003307). States are hairlines, not fills. */
|
|
46
|
+
.gate-pill--escalate { color: var(--danger); }
|
|
47
|
+
.gate-pill--needs_trust { color: var(--warn); }
|
|
48
|
+
.gate-pill--trusted { color: var(--info); }
|
|
54
49
|
|
|
55
50
|
.gate-reasons { list-style: none; padding: 0; margin: 0; }
|
|
56
51
|
.gate-reasons li {
|
|
57
|
-
padding: 6px 0; border-bottom:
|
|
52
|
+
padding: 6px 0; border-bottom: var(--line) solid var(--rule-soft);
|
|
58
53
|
font-size: 13px; color: var(--ink);
|
|
59
54
|
}
|
|
60
55
|
.gate-reasons li:last-child { border-bottom: 0; }
|
|
61
56
|
.gate-reasons code {
|
|
62
|
-
font-family:
|
|
63
|
-
color: var(--accent-
|
|
57
|
+
font-family: var(--font-mono); font-size: 12px;
|
|
58
|
+
color: var(--accent-ink); background: var(--glass);
|
|
64
59
|
padding: 1px 5px; border-radius: 4px;
|
|
65
60
|
}
|
|
66
61
|
.gate-reasons .floor { color: var(--danger); font-weight: 600; }
|
|
67
62
|
|
|
68
63
|
.gate-files { font-size: 12.5px; color: var(--ink-soft); }
|
|
69
|
-
.gate-files code { font-family:
|
|
64
|
+
.gate-files code { font-family: var(--font-mono); }
|
|
70
65
|
|
|
71
66
|
.gate-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 2px; }
|
|
72
67
|
.gate-btn {
|
|
73
68
|
font: inherit; font-size: 13px; font-weight: 600;
|
|
74
|
-
padding: 7px 16px; border:
|
|
75
|
-
background: var(--accent); color:
|
|
69
|
+
padding: 7px 16px; border: var(--line) solid var(--accent);
|
|
70
|
+
background: var(--accent); color: var(--accent-on);
|
|
76
71
|
border-radius: var(--radius-sm); cursor: pointer;
|
|
77
72
|
}
|
|
78
|
-
.gate-btn:hover:not(:disabled) { background: var(--accent-
|
|
73
|
+
.gate-btn:hover:not(:disabled) { background: var(--accent-lift); border-color: var(--accent-lift); }
|
|
79
74
|
.gate-btn:disabled { opacity: 0.45; cursor: default; }
|
|
80
|
-
.gate-btn--ghost { background: var(--
|
|
81
|
-
.gate-btn--ghost:hover:not(:disabled) { background: var(--
|
|
75
|
+
.gate-btn--ghost { background: var(--bg-card); color: var(--ink); border-color: var(--rule); }
|
|
76
|
+
.gate-btn--ghost:hover:not(:disabled) { background: var(--glass); border-color: var(--rule); }
|
|
82
77
|
.gate-approved-note { color: var(--ok); font-size: 13px; }
|
|
83
78
|
|
|
84
79
|
.gate-empty, .gate-sealed { color: var(--ink-soft); padding: 16px 0; }
|
|
@@ -87,10 +82,10 @@
|
|
|
87
82
|
/* Lightweight confirm modal (mirrors harbor). */
|
|
88
83
|
.gate-modal-bg {
|
|
89
84
|
position: fixed; inset: 0; background: color-mix(in srgb, var(--ink) 40%, transparent);
|
|
90
|
-
display: flex; align-items: center; justify-content: center; z-index:
|
|
85
|
+
display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); padding: 20px;
|
|
91
86
|
}
|
|
92
87
|
.gate-modal {
|
|
93
|
-
background: var(--
|
|
88
|
+
background: var(--bg-card); border: var(--line) solid var(--rule); border-radius: var(--radius);
|
|
94
89
|
max-width: 480px; width: 100%; padding: 20px 22px; box-shadow: var(--shadow-pop);
|
|
95
90
|
}
|
|
96
91
|
.gate-modal h2 { color: var(--ink); margin: 0 0 8px; font-size: 17px; font-weight: 600; }
|
|
@@ -19,7 +19,15 @@
|
|
|
19
19
|
<div class="app-body">
|
|
20
20
|
<header class="app-topbar" id="app-topbar"></header>
|
|
21
21
|
<div class="app-content">
|
|
22
|
-
|
|
22
|
+
<!-- task 1003307: the board page head. Gate shipped with NO <h1> at all
|
|
23
|
+
(one-header-main-h1 measured 0 on every render), so the re-skin
|
|
24
|
+
carries the structural fix rather than porting the hole. The heading
|
|
25
|
+
is the LABEL voice, not a display line: on a working surface the
|
|
26
|
+
page's own name is the least interesting thing on it. -->
|
|
27
|
+
<div class="page-head page-head--board">
|
|
28
|
+
<h1 class="page-head__h">Gate</h1>
|
|
29
|
+
<p class="page-head__sub" id="gate-sub">Loading…</p>
|
|
30
|
+
</div>
|
|
23
31
|
|
|
24
32
|
<main id="hall-main">
|
|
25
33
|
<p class="gate-sealed" id="gate-sealed" hidden>Archons only.</p>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "Gate — the access-request queue behind requireGovernmentPage. Same confirm-modal component as harbor, which is why the two had guessed two different z-indexes for it. Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
|
|
3
|
+
"page": "/builders/gate",
|
|
4
|
+
"surface": "hall-ui",
|
|
5
|
+
"stub": {
|
|
6
|
+
"prefix": "/builders/"
|
|
7
|
+
},
|
|
8
|
+
"modeQuery": false,
|
|
9
|
+
"_feeds": "The kit's own stub carries no feed for this page, so against it the page renders its EMPTY and SKELETON states — which is the point: those are states the floors must hold in. Against the hall-preview harness the same states render populated. Every declared 404 below is a fixture the harness does not carry, named rather than hidden.",
|
|
10
|
+
"ignoreRequests": [
|
|
11
|
+
"/api/(gds|bongos)/me$",
|
|
12
|
+
"/api/(gds|bongos)/me/",
|
|
13
|
+
"/api/(gds|bongos)/goals",
|
|
14
|
+
"/api/(gds|bongos)/inbox/",
|
|
15
|
+
"/api/(gds|bongos)/versions",
|
|
16
|
+
"/api/(gds|bongos)/gate-approvals",
|
|
17
|
+
"/api/(gds|bongos)/builders",
|
|
18
|
+
"/api/(gds|bongos)/access-requests"
|
|
19
|
+
],
|
|
20
|
+
"ignoreConsole": [
|
|
21
|
+
"/api/(gds|bongos)/",
|
|
22
|
+
"\\b401\\b",
|
|
23
|
+
"\\b403\\b",
|
|
24
|
+
"\\b404\\b",
|
|
25
|
+
"\\b501\\b",
|
|
26
|
+
"Unauthorized",
|
|
27
|
+
"Forbidden",
|
|
28
|
+
"Not Found",
|
|
29
|
+
"Not Implemented",
|
|
30
|
+
"load failed"
|
|
31
|
+
],
|
|
32
|
+
"states": {
|
|
33
|
+
"queue": {
|
|
34
|
+
"auth": true,
|
|
35
|
+
"actions": [
|
|
36
|
+
[
|
|
37
|
+
"wait",
|
|
38
|
+
700
|
|
39
|
+
]
|
|
40
|
+
],
|
|
41
|
+
"expect": {
|
|
42
|
+
"visible": [
|
|
43
|
+
"#gate-body"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"out": {
|
|
48
|
+
"auth": false
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"reducedMotion": {
|
|
52
|
+
"auth": true,
|
|
53
|
+
"actions": [
|
|
54
|
+
[
|
|
55
|
+
"wait",
|
|
56
|
+
600
|
|
57
|
+
]
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -90,15 +90,32 @@
|
|
|
90
90
|
// goals.html loads task-lib.js before this file (the render-family order).
|
|
91
91
|
const { msOf, taskActivityMs } = window.OTBTaskLib;
|
|
92
92
|
|
|
93
|
-
// task 1003224
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
93
|
+
// task 1003224 made a goal's subtitle a TOOLTIP on a list, because 29 of 38
|
|
94
|
+
// titles already carried their own explanation after a dash and a row would
|
|
95
|
+
// then say the same thing twice.
|
|
96
|
+
//
|
|
97
|
+
// Task 1003307 REVERSES that for the row, on the owner's call, against the
|
|
98
|
+
// approved archetype (docs/design/mocks/hall/goals/v3.html, .goal__sub). Two
|
|
99
|
+
// things changed under 1003224's reasoning: the dash-in-title rate fell to 17
|
|
100
|
+
// of 72, and 35 of those 72 goals now carry a real subtitle that a tooltip
|
|
101
|
+
// hides from anyone reading — and hides COMPLETELY from anyone on a touch
|
|
102
|
+
// screen, where there is no hover. A duplicated explanation is a copy-desk
|
|
103
|
+
// fix; an invisible one is not fixable at all.
|
|
104
|
+
//
|
|
105
|
+
// subtitleAttr survives for the CARD view, which has no room for a line.
|
|
97
106
|
function subtitleAttr(g) {
|
|
98
107
|
const t = (g && g.subtitle ? String(g.subtitle) : '').trim();
|
|
99
108
|
return t ? ` title="${window.OTB.escapeHtml(t)}"` : '';
|
|
100
109
|
}
|
|
101
110
|
|
|
111
|
+
// The row's visible subtitle. Empty string when the goal has none, so the row
|
|
112
|
+
// collapses to title + facts rather than reserving a blank line — the card's
|
|
113
|
+
// "every region hides on null" grammar, applied to a row.
|
|
114
|
+
function subtitleLine(g) {
|
|
115
|
+
const t = (g && g.subtitle ? String(g.subtitle) : '').trim();
|
|
116
|
+
return t ? `<p class="gr-sub">${window.OTB.escapeHtml(t)}</p>` : '';
|
|
117
|
+
}
|
|
118
|
+
|
|
102
119
|
// task 1003224 — the three-layer prose rules for a goal's detail head, kept
|
|
103
120
|
// here rather than in goals-page.js because that file is 500 lines over the
|
|
104
121
|
// excess-lines ratchet and this one exists for exactly that reason. It WRITES
|
|
@@ -120,6 +137,6 @@
|
|
|
120
137
|
ring, memberName,
|
|
121
138
|
readinessOf, EMPTY_ROLLUP, goalRollLine,
|
|
122
139
|
matchesTodoSearch, msOf, taskActivityMs,
|
|
123
|
-
subtitleAttr, applyGoalProse,
|
|
140
|
+
subtitleAttr, subtitleLine, applyGoalProse,
|
|
124
141
|
};
|
|
125
142
|
})();
|