@bongos/core 1.19.1044 → 1.19.1046

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.
Files changed (89) hide show
  1. package/.bongos-core.json +106 -121
  2. package/docs/adr/0337-the-hub-account-is-the-person-a-hall-account-is-their-seat-in-one-project.md +14 -2
  3. package/docs/adr/README.md +1 -1
  4. package/docs/copy-inventory.md +142 -158
  5. package/docs/copy-registry.json +173 -360
  6. package/docs/file-map.md +2 -3
  7. package/docs/module-api-changelog.md +4 -0
  8. package/docs/recipes/windows-builders.md +1 -1
  9. package/modules/hall-ui/public/atlas.html +1 -1
  10. package/modules/hall-ui/public/blockers.html +1 -1
  11. package/modules/hall-ui/public/board-room.html +1 -1
  12. package/modules/hall-ui/public/claim-action.js +250 -0
  13. package/modules/hall-ui/public/collab.css +1 -1
  14. package/modules/hall-ui/public/collab.html +1 -1
  15. package/modules/hall-ui/public/copy-desk.html +1 -1
  16. package/modules/hall-ui/public/deploy.html +1 -1
  17. package/modules/hall-ui/public/diagrams.html +1 -1
  18. package/modules/hall-ui/public/drachmae.html +1 -1
  19. package/modules/hall-ui/public/fleet.html +1 -1
  20. package/modules/hall-ui/public/gate.html +1 -1
  21. package/modules/hall-ui/public/goals-page.js +28 -44
  22. package/modules/hall-ui/public/goals-render.js +7 -28
  23. package/modules/hall-ui/public/goals.html +6 -3
  24. package/modules/hall-ui/public/government.html +1 -1
  25. package/modules/hall-ui/public/idea.html +1 -1
  26. package/modules/hall-ui/public/ideas.html +1 -1
  27. package/modules/hall-ui/public/index.html +1 -1
  28. package/modules/hall-ui/public/modules.html +1 -1
  29. package/modules/hall-ui/public/primer.html +1 -1
  30. package/modules/hall-ui/public/profile.html +1 -1
  31. package/modules/hall-ui/public/project-settings.html +1 -1
  32. package/modules/hall-ui/public/ranks.html +1 -1
  33. package/modules/hall-ui/public/roadmap.html +1 -1
  34. package/modules/hall-ui/public/{people.css → roster.css} +7 -11
  35. package/modules/hall-ui/public/roster.html +5 -5
  36. package/modules/hall-ui/public/roster.js +6 -7
  37. package/modules/hall-ui/public/roster.states.json +1 -1
  38. package/modules/hall-ui/public/sessions.html +1 -1
  39. package/modules/hall-ui/public/settings.html +2 -2
  40. package/modules/hall-ui/public/settings.js +2 -2
  41. package/modules/hall-ui/public/shell.js +3 -10
  42. package/modules/hall-ui/public/studio.html +1 -1
  43. package/modules/hall-ui/public/style.css +2 -9
  44. package/modules/hall-ui/public/task.html +1 -1
  45. package/modules/hall-ui/public/watch.html +1 -1
  46. package/modules/hall-ui/public/work.html +5 -2
  47. package/modules/hall-ui/public/work.js +35 -123
  48. package/modules/hall-ui/records/builders-roster.md +1 -1
  49. package/modules/hall-ui/records/roster-and-ledger.md +2 -2
  50. package/modules/platform-identity/account-visibility.js +3 -3
  51. package/modules/platform-identity/platform-identity.js +2 -2
  52. package/modules/platform-identity/routes/profile.js +1 -1
  53. package/modules/platform-identity/routes/sso.js +4 -3
  54. package/modules/platform-identity/scouting-authz.js +2 -2
  55. package/modules/platform-identity/tests/platform-identity.mjs +1 -1
  56. package/package-lock.json +2 -2
  57. package/package.json +1 -1
  58. package/release-notes.json +12 -0
  59. package/src/bongos/auth.js +9 -24
  60. package/src/bongos/serve-internal.js +13 -19
  61. package/src/module-api.js +1 -1
  62. package/tests/account_privacy_flags.mjs +1 -1
  63. package/tests/auth_resolve_failure.mjs +6 -6
  64. package/tests/claim_action.mjs +417 -0
  65. package/tests/core_upgrade_owner_door.mjs +1 -1
  66. package/tests/edit_hints.mjs +8 -8
  67. package/tests/effective_visibility_predicate.mjs +1 -1
  68. package/tests/goal_category_ui.mjs +3 -0
  69. package/tests/goal_criterion_confirm_ui.mjs +3 -0
  70. package/tests/goal_forest_page.mjs +3 -0
  71. package/tests/goal_invite_consent.mjs +3 -1
  72. package/tests/goal_mine_lens.mjs +3 -0
  73. package/tests/government_parity.mjs +1 -1
  74. package/tests/hall_builders_page_pass.mjs +2 -2
  75. package/tests/hall_mine_lens.mjs +3 -0
  76. package/tests/hall_nav.mjs +8 -8
  77. package/tests/hall_page_gate_map.mjs +14 -11
  78. package/tests/hall_roster_world.mjs +47 -78
  79. package/tests/module_contributions.mjs +0 -1
  80. package/tests/nav_permission_atoms.mjs +1 -1
  81. package/tests/{scouting_page_gate.mjs → page_gate_second_door.mjs} +34 -29
  82. package/tests/profile_rollup_consent.mjs +4 -4
  83. package/tests/profile_route.mjs +3 -26
  84. package/tests/scouting_owner_access_and_reach.mjs +4 -8
  85. package/modules/hall-ui/public/people.html +0 -79
  86. package/modules/hall-ui/public/people.js +0 -321
  87. package/modules/hall-ui/public/people.states.json +0 -89
  88. package/tests/people_directory_clip.mjs +0 -269
  89. package/tests/people_name_only.mjs +0 -263
@@ -1,321 +0,0 @@
1
- // people.js — the People page: the cross-project builder directory (task
2
- // 1002577; ADR 0141 §4 is the data's design of record), served at /people —
3
- // task 1003470 first made its legacy door /scouting render this same script,
4
- // and task 1003440 deleted that door (the URL 301s here), because the
5
- // same /api/bongos/scouting rollup was being drawn three
6
- // different ways (a kit ledger here, a hand-built table there, and the same
7
- // columns in a different order). The endpoint is gated server-side on
8
- // 'project.curate' OR being a project owner (R14, ADR 0210); this page is
9
- // gated in serve-internal.js on that same pair, so a visitor who is neither
10
- // never sees this shell.
11
- //
12
- // What a directory row is (task 1003470): WHO — the avatar the API returns and
13
- // both pages dropped, the display name, the login under it as the door (GitHub
14
- // is the identity the platform account is keyed on, and the one page every
15
- // listed builder has: the directory is cross-project, so no local profile id
16
- // exists); then the four figures in tabular columns, the crafts as chips, and
17
- // when they were last seen. Search, a sort and a craft lens are the kit's
18
- // filter bar; the rows page through the kit's pager.
19
- //
20
- // THE SECOND TIER (task 1002291, ADR 0334). The response also carries
21
- // `name_only`: builders who hid their cross-project record but are still open to
22
- // recruiting, which privacy spec D2 lists "name-only". They get their own panel
23
- // of identity cells because they have no record to rank, sort or filter by role:
24
- // the lenses below leave them alphabetical, a search reads their name, and a
25
- // role filter never matches them.
26
- // All network values render through OTBKit.esc — never raw innerHTML.
27
- (function () {
28
- 'use strict';
29
- var kit = window.OTBKit;
30
- var OTB = window.OTB;
31
- var esc = kit.esc;
32
- var body = document.getElementById('people-body');
33
- var sub = document.getElementById('people-sub');
34
- var countPill = document.getElementById('people-count');
35
- var foot = document.getElementById('people-foot');
36
- var namedScroll = document.getElementById('people-named-scroll');
37
- var namedCount = document.getElementById('people-named-count');
38
- var namedBody = document.getElementById('people-named-body');
39
- var namedFoot = document.getElementById('people-named-foot');
40
-
41
- function fmtRecency(iso) {
42
- if (!iso) return '—';
43
- var t = Date.parse(iso);
44
- if (isNaN(t)) return '—';
45
- var days = Math.floor((Date.now() - t) / 86400000);
46
- if (days <= 0) return 'today';
47
- if (days === 1) return '1 day ago';
48
- if (days < 30) return days + ' days ago';
49
- return Math.floor(days / 30) + ' mo ago';
50
- }
51
- var fmtInt = function (n) { return OTB && OTB.fmtInt ? OTB.fmtInt(n) : String(n == null ? 0 : n); };
52
- var rankLabel = function (r) { return OTB && OTB.rankLabel ? OTB.rankLabel(r) : r; };
53
- // A ROW TAG TAKES roleLabel() (dom-utils.js, task 1004041). Without it the Directory
54
- // printed the column: lowercase 'engineer', 'ui' instead of 'UI', and — for a builder
55
- // who has set no role — 'unclassified', which is the example V2 names, in the exact
56
- // place it names it. Same defensive shape as rankLabel above: the pack may be absent.
57
- var roleLabel = function (d) { return OTB && OTB.roleLabel ? OTB.roleLabel(d) : String(d); };
58
- var currencyLabel = function () {
59
- var b = window.OTBBranding;
60
- return (b && b.currencyLabel && b.currencyLabel({ caps: true })) || 'Credits';
61
- };
62
-
63
- function builderName(b) {
64
- return b.display_name || b.github_login || ('#' + b.github_id);
65
- }
66
- function initialOf(b) {
67
- var n = String(builderName(b)).replace(/^[@#]/, '');
68
- return (n.charAt(0) || '?').toUpperCase();
69
- }
70
-
71
- // The identity cell. The name is the shell's .lb-name (a door that reads as
72
- // text until hovered) when a login exists to open; the login sits under it in
73
- // mono so the door's destination is never a surprise.
74
- function whoHtml(b) {
75
- var name = esc(builderName(b));
76
- var avatar = b.avatar_url
77
- ? '<img class="dir-avatar" src="' + esc(b.avatar_url) + '" alt="" loading="lazy">'
78
- : '<span class="dir-avatar dir-avatar--initial" aria-hidden="true">' + esc(initialOf(b)) + '</span>';
79
- var nameHtml = b.github_login
80
- ? '<a class="lb-name dir-name" href="https://github.com/' + encodeURIComponent(b.github_login) + '" rel="noopener">' + name + '</a>'
81
- : '<span class="dir-name">' + name + '</span>';
82
- var login = b.github_login ? '<span class="dir-login">@' + esc(b.github_login) + '</span>' : '';
83
- return '<span class="dir-who">' + avatar + '<span class="dir-who__t">' + nameHtml + login + '</span></span>';
84
- }
85
- function craftsHtml(b) {
86
- var list = Array.isArray(b.disciplines) ? b.disciplines : [];
87
- if (!list.length) return '<span class="dir-none">—</span>';
88
- return '<span class="dir-crafts">' + list.map(function (d) {
89
- return '<span class="fact-chip">' + esc(roleLabel(d)) + '</span>';
90
- }).join('') + '</span>';
91
- }
92
-
93
- // THE DIRECTORY ASKS FOR THE ENDPOINT MAXIMUM, so a full response is the only
94
- // truncation signal that exists. `GET /scouting` clamps at parsePagination
95
- // maxLimit: 500, takes no offset, and `listScoutingRollup` returns rows with no
96
- // count of the whole set — so `length === DIRECTORY_LIMIT` means "at least this
97
- // many", never "exactly this many", and there is nothing else to read it from.
98
- // ONE constant feeds the request AND every sentence written about it, so the
99
- // number a reader is shown can never drift from the number that was asked for.
100
- //
101
- // This is part 1 of task 1003110 — the honest half, which removes the
102
- // silent-lie property whatever the real count turns out to be. Part 2 is
103
- // server-offset paging, and it is deliberately NOT here: the kit has carried
104
- // the mode since task 1003281 (`makeLedger({ serverPager, onPage })`), but the
105
- // ROUTE cannot serve it — no offset parameter, no total, a hard 500 ceiling —
106
- // so paging this page is a server change first. Its trigger is a directory
107
- // approaching ~400; a read on 2026-09-16 returned far fewer.
108
- var DIRECTORY_LIMIT = 500;
109
-
110
- var all = [];
111
- var named = [];
112
- var query = '';
113
- var craft = '';
114
- var sortBy = '';
115
-
116
- function matches(b) {
117
- if (craft && !(Array.isArray(b.disciplines) && b.disciplines.indexOf(craft) !== -1)) return false;
118
- if (!query) return true;
119
- var hay = ((b.github_login || '') + ' ' + (b.display_name || '') + ' ' +
120
- (Array.isArray(b.disciplines) ? b.disciplines.join(' ') : '')).toLowerCase();
121
- return hay.indexOf(query) !== -1;
122
- }
123
- // A name-only row carries no roles (they are part of the hidden record), so a
124
- // role filter never matches it; a search reads the name.
125
- function matchesNamed(b) {
126
- if (craft) return false;
127
- if (!query) return true;
128
- return ((b.github_login || '') + ' ' + (b.display_name || '')).toLowerCase().indexOf(query) !== -1;
129
- }
130
- // A count that cannot overstate a clipped read: a full response means "at least".
131
- function countText(n) {
132
- return n >= DIRECTORY_LIMIT ? fmtInt(DIRECTORY_LIMIT) + '+' : fmtInt(n);
133
- }
134
- // The server's order IS "track record" (ADR 0141 §4 ranks the rollup); the
135
- // other lenses re-order the loaded set client-side, ties keeping that order.
136
- var SORTS = {
137
- '': null,
138
- ships: function (b) { return -(b.total_tasks_shipped || 0); },
139
- credits: function (b) { return -(b.total_credits || 0); },
140
- karma: function (b) { return -(b.total_karma || 0); },
141
- projects: function (b) { return -(b.project_count || 0); },
142
- recent: function (b) { var t = Date.parse(b.last_active || ''); return isNaN(t) ? Infinity : -t; },
143
- };
144
- function ordered(rows) {
145
- var key = SORTS[sortBy];
146
- if (!key) return rows;
147
- return rows.map(function (b, i) { return { b: b, i: i }; })
148
- .sort(function (x, y) { return (key(x.b) - key(y.b)) || (x.i - y.i); })
149
- .map(function (x) { return x.b; });
150
- }
151
-
152
- var pager = kit.makePager('people', 'hall-people-per-page');
153
- var ledger = null;
154
- var namedPager = kit.makePager('people-named', 'hall-people-named-per-page');
155
- var namedLedger = null;
156
-
157
- function rowHtml(b) {
158
- return '<tr>' +
159
- '<td>' + whoHtml(b) + '</td>' +
160
- '<td class="ledger__num">' + esc(fmtInt(b.project_count != null ? b.project_count : 0)) + '</td>' +
161
- '<td class="ledger__num">' + esc(fmtInt(b.total_tasks_shipped != null ? b.total_tasks_shipped : 0)) + '</td>' +
162
- '<td class="ledger__num">' + esc(fmtInt(b.total_credits != null ? b.total_credits : 0)) + '</td>' +
163
- '<td class="ledger__num">' + esc(fmtInt(b.total_karma != null ? b.total_karma : 0)) + '</td>' +
164
- '<td>' + craftsHtml(b) + '</td>' +
165
- '<td class="ledger__date">' + esc(fmtRecency(b.last_active)) + '</td>' +
166
- '</tr>';
167
- }
168
-
169
- // The identity cell and nothing else: every other column is the record hidden.
170
- function namedRowHtml(b) {
171
- return '<tr><td>' + whoHtml(b) + '</td></tr>';
172
- }
173
-
174
- function rerender() {
175
- if (ledger) ledger.render(ordered(all.filter(matches)));
176
- if (namedLedger) namedLedger.render(named.filter(matchesNamed));
177
- }
178
-
179
- function mountNamed() {
180
- if (!namedScroll || !named.length) return;
181
- namedScroll.hidden = false;
182
- if (namedCount) {
183
- namedCount.textContent = countText(named.length);
184
- namedCount.hidden = false;
185
- }
186
- // The ranked footnote's rule, for the one lens that reads this list: a full
187
- // response is clipped, and a search cannot find a builder it never loaded.
188
- var namedClipped = named.length >= DIRECTORY_LIMIT;
189
- if (namedFoot) {
190
- namedFoot.textContent = namedClipped
191
- ? 'This list is clipped at the first ' + fmtInt(DIRECTORY_LIMIT) + ' by login. Search only reads what this page loaded, so a builder past that ' + fmtInt(DIRECTORY_LIMIT) + ' will not appear in it.'
192
- : '';
193
- namedFoot.hidden = !namedClipped;
194
- }
195
- namedLedger = kit.makeLedger({
196
- mount: namedBody,
197
- columns: ['Builder'],
198
- rowHtml: namedRowHtml,
199
- emptyMsg: 'No builder listed by name only matches these filters.',
200
- pager: namedPager,
201
- });
202
- }
203
-
204
- function mountDirectory(builders, nameOnly) {
205
- all = Array.isArray(builders) ? builders : [];
206
- named = Array.isArray(nameOnly) ? nameOnly : [];
207
- if (namedScroll) namedScroll.hidden = true;
208
- // An EMPTY directory is almost never missing data — it is ADR 0171's
209
- // fail-closed consent boundary doing exactly what it was ratified to do.
210
- // `listScoutingRollup` filters on `profile_state = 'active'`, every account
211
- // starts `'provisional'`, and an account activates ONLY when its human signs
212
- // in at the hub itself (P03, ratified by the owner 2026-08-16: no backfill
213
- // activation). This builders hall predates the hub flow, so its builders stay
214
- // unlisted until each has signed in there once.
215
- //
216
- // Reporting that as "no cross-project activity reported yet" is actively
217
- // misleading — the activity exists and is visible on every project's own
218
- // leaderboard; the accounts simply are not publicly listed — and that wrong
219
- // explanation is why an empty directory got filed as a bug (task 1002937).
220
- // Say which of the two it is, so the page is never mistaken for broken.
221
- if (!all.length && !named.length) {
222
- notice('Nobody is publicly listed here yet. A builder joins this directory once they have '
223
- + 'signed in on the main platform site at least once — accounts stay unlisted until then, '
224
- + 'and none are listed without it. Their work still shows on each project’s own ledger.');
225
- return;
226
- }
227
- // A FULL PAGE IS A CLIPPED PAGE. Every sentence below has to hedge when this
228
- // is true, because each of them otherwise states a total the page cannot know.
229
- var clipped = all.length >= DIRECTORY_LIMIT;
230
- // The second tier, named in the same sentence so the ranked count is never
231
- // read as everyone the directory lists.
232
- var namedPart = named.length ? '; ' + countText(named.length) + ' more by name only' : '';
233
- if (countPill) {
234
- countPill.textContent = clipped ? fmtInt(DIRECTORY_LIMIT) + '+' : String(all.length);
235
- countPill.hidden = false;
236
- }
237
- if (sub) {
238
- var listed = clipped
239
- ? 'Showing the first ' + fmtInt(DIRECTORY_LIMIT) + ' builders across hosted projects, ranked by track record — there are more than this page can load' + namedPart
240
- : all.length
241
- ? fmtInt(all.length) + ' builder' + (all.length === 1 ? '' : 's') + ' listed across hosted projects, ranked by track record' + namedPart
242
- // Nobody ranked yet: "0 builders ranked; 2 more by name only" would read as a count of nothing.
243
- : countText(named.length) + ' builder' + (named.length === 1 ? '' : 's') + ' listed across hosted projects by name only';
244
- sub.textContent = listed + '. Descriptive only — cross-project numbers never carry authority here.';
245
- }
246
- // THE LENSES LIE HARDER THAN THE COUNT DOES, and that is worth its own
247
- // sentence. Search, sort and the craft filter all re-order the set this page
248
- // already loaded (see SORTS above) — so on a clipped directory "most karma"
249
- // is the most karma AMONG THE TOP 500 BY TRACK RECORD, and a builder outside
250
- // that 500 cannot be found by any of them. A reader who is told only that the
251
- // list is long would still trust the search.
252
- if (foot) {
253
- foot.textContent = clipped
254
- ? 'The directory is clipped at the first ' + fmtInt(DIRECTORY_LIMIT) + ' by track record. Search and the sort lenses only re-order what this page loaded, so a builder outside that ' + fmtInt(DIRECTORY_LIMIT) + ' will not appear in them.'
255
- : '';
256
- foot.hidden = !clipped;
257
- }
258
- var crafts = [];
259
- all.forEach(function (b) {
260
- (Array.isArray(b.disciplines) ? b.disciplines : []).forEach(function (d) {
261
- if (crafts.indexOf(d) === -1) crafts.push(d);
262
- });
263
- });
264
- crafts.sort();
265
- kit.makeFilterBar({
266
- mount: document.getElementById('people-filters'),
267
- search: { id: 'people-q', label: 'Search', placeholder: `name or ${window.OTB.roleAxisLabel().toLowerCase()}` },
268
- primary: [
269
- { id: 'people-sort', label: 'Sort', options: [
270
- { value: '', label: 'track record' }, { value: 'ships', label: 'most ships' },
271
- { value: 'credits', label: 'most ' + currencyLabel().toLowerCase() }, { value: 'karma', label: 'most karma' },
272
- { value: 'projects', label: 'most projects' }, { value: 'recent', label: 'most recently active' }] },
273
- { id: 'people-craft', label: window.OTB.roleAxisLabel(), options: [{ value: '', label: '— any —' }].concat(crafts.map((c) => ({ value: c, label: window.OTB.roleLabel(c) }))) },
274
- ],
275
- onChange: function (vals) {
276
- query = String(vals['people-q'] || '').trim().toLowerCase();
277
- craft = String(vals['people-craft'] || '');
278
- sortBy = String(vals['people-sort'] || '');
279
- pager.page = 1;
280
- namedPager.page = 1;
281
- rerender();
282
- },
283
- });
284
- body.textContent = '';
285
- body.className = '';
286
- ledger = kit.makeLedger({
287
- mount: body,
288
- columns: ['Builder', { label: 'Projects', class: 'ledger__num' }, { label: 'Ships', class: 'ledger__num' },
289
- { label: currencyLabel(), class: 'ledger__num' }, { label: 'Karma', class: 'ledger__num' }, `${window.OTB.roleAxisLabel()}s`, 'Last active'],
290
- rowHtml: rowHtml,
291
- // With ranked builders, reached only when the lenses excluded them all;
292
- // without, the directory lists hidden builders alone (the panel below) —
293
- // the fully empty case returns above with its own explanation.
294
- emptyMsg: all.length ? 'No listed builder matches that search.' : 'No builder with a public track record is listed yet.',
295
- pager: pager,
296
- });
297
- mountNamed();
298
- rerender();
299
- }
300
-
301
- function notice(msg) {
302
- body.innerHTML = '';
303
- body.className = 'note';
304
- body.textContent = msg;
305
- }
306
-
307
- fetch('/api/bongos/scouting?limit=' + DIRECTORY_LIMIT, { headers: { Accept: 'application/json' } })
308
- .then(function (r) {
309
- if (r.status === 403 || r.status === 401) { throw { gated: true }; }
310
- if (!r.ok) throw new Error('http ' + r.status);
311
- return r.json();
312
- })
313
- .then(function (data) { mountDirectory(data && data.builders, data && data.name_only); })
314
- .catch(function (e) {
315
- // The floor is the pack's label for metic, never a hardcoded rank name —
316
- // and the page used to say "Archon-only", which was wrong since ADR 0210.
317
- notice(e && e.gated
318
- ? 'The directory opens at the ' + rankLabel('metic') + ' rank, or to a project’s owner.'
319
- : 'Couldn’t load the directory right now.');
320
- });
321
- }());
@@ -1,89 +0,0 @@
1
- {
2
- "_": "People — the cross-project directory behind requireProjectCuratePage (metic+ via project.curate, or a project owner). Descriptive only; it grants no authority, and the page says so above the fold. Written with the re-skin (task 1003307); the redesign (task 1003470) added the identity cell, the sort and craft lenses, and the `search` state. Its legacy door /scouting was deleted in task 1003440; the URL 301s here. Populated look: the hall-preview harness (scripts/hall-preview/fixtures/scouting.json carries five builders, three with avatars, plus two listed by name only — task 1002291 added that second panel; the `search` state shows its empty case).",
3
- "page": "/builders/people",
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)/builders",
17
- "/api/(gds|bongos)/scouting",
18
- "/api/(gds|bongos)/public/"
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
- "directory": {
34
- "auth": true,
35
- "actions": [
36
- [
37
- "wait",
38
- 700
39
- ]
40
- ],
41
- "expect": {
42
- "visible": [
43
- "#people-scroll"
44
- ]
45
- }
46
- },
47
- "search": {
48
- "auth": true,
49
- "actions": [
50
- [
51
- "wait",
52
- 700
53
- ],
54
- [
55
- "fill",
56
- "#people-q",
57
- "hyp"
58
- ],
59
- [
60
- "wait",
61
- 200
62
- ]
63
- ],
64
- "expect": {
65
- "visible": [
66
- "#people-scroll"
67
- ],
68
- "value": [
69
- [
70
- "#people-q",
71
- "hyp"
72
- ]
73
- ]
74
- }
75
- },
76
- "out": {
77
- "auth": false
78
- }
79
- },
80
- "reducedMotion": {
81
- "auth": true,
82
- "actions": [
83
- [
84
- "wait",
85
- 600
86
- ]
87
- ]
88
- }
89
- }