@bongos/core 1.19.387 → 1.19.389
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 +144 -59
- package/.claude/skills/grade-recover/SKILL.md +1 -1
- package/.claude/skills/grader-health/SKILL.md +1 -1
- package/config/branding.neutral.json +19 -19
- package/config/design-tokens.neutral.json +31 -36
- package/docs/adr/0196-chrome-world-token-contract-and-the-landing-sheets.md +31 -0
- package/docs/adr/README.md +1 -0
- package/docs/branding-contract.md +1 -1
- package/docs/copy-inventory.md +93 -67
- package/docs/copy-registry.json +411 -133
- package/docs/file-map.md +15 -0
- package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
- package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
- package/modules/dev-box/app/assets/tray/win-off.png +0 -0
- package/modules/dev-box/app/assets/tray/win-on.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
- package/modules/dev-box/app/build-resources/icon.png +0 -0
- package/modules/dev-box/app/renderer/index.html +1 -1
- package/modules/dev-box/app/renderer/styles.css +3 -1
- package/modules/dev-box/app/renderer/theme.generated.css +13 -13
- package/modules/dev-box/app/scripts/gen-brand.js +13 -13
- package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +3 -3
- package/modules/dev-box/app/scripts/gen-icons.js +3 -3
- package/modules/dev-box/app/src/brand.generated.json +1 -1
- package/modules/grading/grader-config.js +5 -3
- package/modules/grading/grader-rubric.json +2 -2
- package/modules/grading/grader-score.js +86 -33
- package/modules/grading/grader-workers/index.js +19 -0
- package/modules/hall-ui/public/builders.js +8 -3
- package/modules/provisioning/routes/provisioning.js +4 -4
- package/modules/status-ui/public/explore.html +12 -6
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/assets/cosmos.css +82 -64
- package/public-landing/assets/world/og-card.jpg +0 -0
- package/public-landing/assets/world/r2-bongos-chrome-a-cut.webp +0 -0
- package/public-landing/assets/world/r2-bongos-chrome-a-cut.webp.json +12 -0
- package/public-landing/assets/world/r2-bongos-chrome-b.jpg +0 -0
- package/public-landing/assets/world/r2-bongos-chrome-b.jpg.json +12 -0
- package/public-landing/assets/world/r2-chrome-blob-one-cut.webp +0 -0
- package/public-landing/assets/world/r2-chrome-blob-one-cut.webp.json +13 -0
- package/public-landing/assets/world/r2-chrome-blob-one.jpg +0 -0
- package/public-landing/assets/world/r2-chrome-blob-one.jpg.json +12 -0
- package/public-landing/assets/world/r2-chrome-blobs-set-cut.webp +0 -0
- package/public-landing/assets/world/r2-chrome-blobs-set-cut.webp.json +13 -0
- package/public-landing/assets/world/r2-chrome-blobs-set.jpg +0 -0
- package/public-landing/assets/world/r2-chrome-blobs-set.jpg.json +12 -0
- package/public-landing/assets/world.css +241 -0
- package/public-landing/contact.html +1 -1
- package/public-landing/index.html +1139 -580
- package/public-landing/privacy.html +1 -1
- package/public-landing/projects.html +2 -2
- package/public-landing/terms.html +1 -1
- package/scripts/gds/ship-grade-steps.js +27 -0
- package/src/bongos/platform-visibility-gate.js +8 -7
- package/src/bongos/stealth-gate.js +9 -8
- package/src/module-api.js +5 -1
- package/src/ui/adapters/claude-design/index.js +2 -2
- package/tests/cloud_bongos_pack.mjs +22 -18
- package/tests/cosmos_token_contrast.mjs +23 -8
- package/tests/grader.mjs +7 -6
- package/tests/grader_quality_window_overflow.mjs +324 -0
- package/tests/landing_legal_pages.mjs +8 -5
- package/tests/landing_page.mjs +295 -166
- package/tests/platform_boot.mjs +3 -1
- package/tests/projects_hub.mjs +9 -5
- package/tests/projects_hub_pre_uat.mjs +3 -1
- package/tests/world_tokens.mjs +351 -0
package/docs/file-map.md
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
/
|
|
10
10
|
├── CLAUDE.md ← index + framing (descriptive; DB is source of truth for state)
|
|
11
11
|
├── README.md ← public-facing one-paragraph summary
|
|
12
|
+
├── PRODUCT.md ← durable product truth for the apex/hall/status surfaces (impeccable init, task 1003296): users, positioning, constraints, brand commitments, principles — no palette, no type
|
|
13
|
+
├── DESIGN.md ← the visual rulebook written FROM the built landing (task 1003298, ADR 0196): palette + derived recipes, type, materials (the chrome plates), components, the motion grammar, both modes; what H1 (hall) and S1 (status) build against. Sidecar .impeccable/design.json
|
|
14
|
+
├── .impeccable/ ← impeccable skill artifacts: config.json (buildPath: code), surfaces/<route>.md (per-route briefs), mocks/world-assets/ (Higgsfield renders + prompt sidecars; the SOURCE of public-landing/assets/world/), mocks/decision/ (A1 comps), design.json (DESIGN.md sidecar), review/ (finish captures)
|
|
12
15
|
├── .gitignore
|
|
13
16
|
├── package.json / package-lock.json
|
|
14
17
|
├── CODEOWNERS ← owner review on the merge-gate surfaces (real since task 1002611, ADR 0159); inert until branch protection is on (scripts/gds/gating.js) — keep aligned with gate-review.js HARD_FLOOR_GLOBS
|
|
@@ -246,6 +249,17 @@
|
|
|
246
249
|
│ ├── assets/tray/ + build-resources/ ← generated icons (scripts/gen-icons.js; build-resources name dodges the global build/ gitignore)
|
|
247
250
|
│ └── test/unit.mjs ← hermetic unit tests (run by the CI workflow, not the root gate)
|
|
248
251
|
│
|
|
252
|
+
├── public-landing/ ← the APEX front door + hub surfaces served by src/platform-server.js (landingPage(): apex-only strip → brand-token stamp → theme injection → ?v= asset stamp). Ships to EVERY instance; <!--apex-only:start/end--> regions are removed on a child
|
|
253
|
+
│ ├── index.html ← the landing (/) — v3 "the template's page" of the chrome world (task 1003298, ADR 0196): server-stamped head, the breath (CSS-only signature), live figures/ledger/orbs from the public feeds baked inside sentinels; page-local <style> only (no :root), links /assets/world.css
|
|
254
|
+
│ ├── projects.html ← the hub (/projects?view=map|mine|manage|new) on cosmos.css (A4, task 1003299, rebuilds it in the world)
|
|
255
|
+
│ ├── privacy.html / terms.html / contact.html ← the footer doors (task 1003251), on cosmos.css
|
|
256
|
+
│ ├── assets/
|
|
257
|
+
│ │ ├── world.css ← the WORLD token layer (ADR 0196): contract tier = the pack, derived tier both modes, root-absolute plate token pairs, the reduced-motion kill switch; no page composition
|
|
258
|
+
│ │ ├── world/ ← the six production plates + <file>.json provenance sidecars (embed-prompt.mjs --scan clean): r2-chrome-blobs-set.jpg, r2-chrome-blob-one.jpg, r2-bongos-chrome-b.jpg (black plates, dark mode, lighten) and their -cut.webp alpha twins (light mode); og-card.jpg (the social card, captured from the page)
|
|
259
|
+
│ │ ├── cosmos.css ← the HUB component sheet (task 1002696): contract tier synced to the pack, its own derived + dark tiers, the .btn/.chip/.strip/.proj/.tbl vocabulary; measured by tests/cosmos_token_contrast.mjs
|
|
260
|
+
│ │ └── verro-medallion.png ← the Verro Labs mark (apex-only block)
|
|
261
|
+
│ └── world/assets/ ← the RETIRED gate's clouds/creatures/plates (task 1002407; the gate folded into / in 1003233) — not the chrome plates
|
|
262
|
+
│
|
|
249
263
|
├── public/ ← example.com — the game (product)
|
|
250
264
|
│ ├── index.html
|
|
251
265
|
│ ├── assets/
|
|
@@ -321,6 +335,7 @@ tests/
|
|
|
321
335
|
├── terrain_picker.mjs ← (ADR 0012): picker dispatch shape + GROUND-ONLY invariant (objects must never affect tile selection).
|
|
322
336
|
├── walkability.mjs ← (ADR 0012): isBlocked over the actual INITIAL_MAP for sea / sand / grass / rock-on-grass / all 8 container cells / vendor cell / cell south of vendor / out-of-bounds. Loads server-side src/world/{map,terrain}.js directly so server logic is exercised.
|
|
323
337
|
├── grader.mjs ← (task 197): pure scoring functions + weight blending + end-to-end grade() per kind. Run with `node tests/grader.mjs`.
|
|
338
|
+
├── grader_quality_window_overflow.mjs ← (task 1003318): a Quality worker that dies on a context-window overflow is PROMPT_TOO_LONG (no retry), a null axis, and a server-side lens outage → manual-confirm, never a fabricated 0/10; the card, the forged-flag and blocker-beside-outage shapes.
|
|
324
339
|
├── session_records.mjs ← (6D.1, ADR 0027): scrubSecrets (ADR 0022 shapes + JWT/DSN/assignments) + buildSessionDigest + resolveTranscriptPath (worktree-session lookup, #551). Fixtures built at runtime so no literal secret hits the scanner.
|
|
325
340
|
├── session_search.mjs ← (6D.2): the session-search ORDER BY whitelist (injection guard) + LIMIT clamp.
|
|
326
341
|
├── session_eval.mjs ← (6D.3 + 6D.4): classifyTurn / computeOverhead / detectFootguns / summarizeSystemicFindings, incl. a #506-shaped fixture.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<title>Dev Box</title>
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&family=Manrope:wght@300;400;500;600&display=swap" rel="stylesheet">
|
|
11
11
|
<link rel="stylesheet" href="theme.generated.css">
|
|
12
12
|
<link rel="stylesheet" href="styles.css">
|
|
13
13
|
</head>
|
|
@@ -154,7 +154,9 @@ main {
|
|
|
154
154
|
width: 100%;
|
|
155
155
|
margin-top: 10px;
|
|
156
156
|
}
|
|
157
|
-
|
|
157
|
+
/* the hover fill is the raw accent; the chrome world's accent carries a light ink
|
|
158
|
+
at 2.19:1, so the label flips to --ink on it (8.12:1) — task 1003298 */
|
|
159
|
+
.btn:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: var(--ink); }
|
|
158
160
|
.btn:disabled { opacity: 0.55; cursor: default; }
|
|
159
161
|
.btn--ghost {
|
|
160
162
|
background: transparent;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/* GENERATED by scripts/gen-brand.js from config/branding.json — do not edit by hand. */
|
|
2
2
|
:root {
|
|
3
|
-
--bg: #
|
|
4
|
-
--bg-card: #
|
|
5
|
-
--bg-deep: #
|
|
6
|
-
--ink: #
|
|
7
|
-
--ink-soft: #
|
|
8
|
-
--ink-faint: #
|
|
9
|
-
--rule: #
|
|
10
|
-
--rule-soft: #
|
|
11
|
-
--accent: #
|
|
12
|
-
--accent-deep: #
|
|
13
|
-
--terracotta: #
|
|
14
|
-
--font-display: "
|
|
15
|
-
--font-body: "
|
|
3
|
+
--bg: #edecee;
|
|
4
|
+
--bg-card: #fbfafc;
|
|
5
|
+
--bg-deep: #e2e1e4;
|
|
6
|
+
--ink: #17181a;
|
|
7
|
+
--ink-soft: #55565a;
|
|
8
|
+
--ink-faint: #65656a;
|
|
9
|
+
--rule: #c6c6c8;
|
|
10
|
+
--rule-soft: #dcdbdd;
|
|
11
|
+
--accent: #fb9569;
|
|
12
|
+
--accent-deep: #a3481a;
|
|
13
|
+
--terracotta: #c9512c;
|
|
14
|
+
--font-display: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
15
|
+
--font-body: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
16
16
|
}
|
|
@@ -73,7 +73,7 @@ function buildBrand(branding) {
|
|
|
73
73
|
// Panel header epigraph (branding copy.tagline).
|
|
74
74
|
TAGLINE: (branding.copy && branding.copy.tagline) || '',
|
|
75
75
|
// Pre-CSS window background (main.js) — the theme bg so first paint is on-brand.
|
|
76
|
-
BG_COLOR: colors.bg || '#
|
|
76
|
+
BG_COLOR: colors.bg || '#fbfafc',
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -85,19 +85,19 @@ function buildThemeCss(branding) {
|
|
|
85
85
|
const v = (x, fb) => x || fb;
|
|
86
86
|
return `/* GENERATED by scripts/gen-brand.js from config/branding.json — do not edit by hand. */
|
|
87
87
|
:root {
|
|
88
|
-
--bg: ${v(c.bg, '#
|
|
89
|
-
--bg-card: ${v(c.bgCard, '#
|
|
90
|
-
--bg-deep: ${v(c.bgDeep, '#
|
|
91
|
-
--ink: ${v(c.ink, '#
|
|
92
|
-
--ink-soft: ${v(c.inkSoft, '#
|
|
88
|
+
--bg: ${v(c.bg, '#edecee')};
|
|
89
|
+
--bg-card: ${v(c.bgCard, '#fbfafc')};
|
|
90
|
+
--bg-deep: ${v(c.bgDeep, '#e2e1e4')};
|
|
91
|
+
--ink: ${v(c.ink, '#17181a')};
|
|
92
|
+
--ink-soft: ${v(c.inkSoft, '#55565a')};
|
|
93
93
|
--ink-faint: ${v(c.inkFaint, '#785a41')};
|
|
94
|
-
--rule: ${v(c.rule, '#
|
|
95
|
-
--rule-soft: ${v(c.ruleSoft, '#
|
|
96
|
-
--accent: ${v(c.accent, '#
|
|
97
|
-
--accent-deep: ${v(c.accentDeep, '#
|
|
98
|
-
--terracotta: ${v(c.terracotta, '#
|
|
99
|
-
--font-display: ${v(fonts.display, '"
|
|
100
|
-
--font-body: ${v(fonts.body, '"
|
|
94
|
+
--rule: ${v(c.rule, '#c6c6c8')};
|
|
95
|
+
--rule-soft: ${v(c.ruleSoft, '#dcdbdd')};
|
|
96
|
+
--accent: ${v(c.accent, '#fb9569')};
|
|
97
|
+
--accent-deep: ${v(c.accentDeep, '#a3481a')};
|
|
98
|
+
--terracotta: ${v(c.terracotta, '#c9512c')};
|
|
99
|
+
--font-display: ${v(fonts.display, '"Manrope", "Segoe UI", system-ui, sans-serif')};
|
|
100
|
+
--font-body: ${v(fonts.body, '"Manrope", "Segoe UI", system-ui, -apple-system, sans-serif')};
|
|
101
101
|
}
|
|
102
102
|
`;
|
|
103
103
|
}
|
|
@@ -68,9 +68,9 @@ ICON = 100 # dmg.iconSize
|
|
|
68
68
|
# it, so its "fallback" would paint a Cloud Bongos colour into a fully-specified
|
|
69
69
|
# host build. That is exactly what `sea` did to the Applications-well rim.
|
|
70
70
|
COLOR_ROLES = {
|
|
71
|
-
"bg": "#
|
|
72
|
-
"ink": "#
|
|
73
|
-
"accent": "#
|
|
71
|
+
"bg": "#edecee", "bgDeep": "#e2e1e4", "bgCard": "#fbfafc",
|
|
72
|
+
"ink": "#17181a", "inkSoft": "#55565a", "ruleSoft": "#dcdbdd",
|
|
73
|
+
"accent": "#fb9569", "accentDeep": "#a3481a", "terracotta": "#c9512c",
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
FONT_DIRS = (
|
|
@@ -62,9 +62,9 @@ const OUT_BUILD = path.join(APP_DIR, 'build-resources');
|
|
|
62
62
|
// it has nothing prompting a host to define it, so its "fallback" would paint a
|
|
63
63
|
// Cloud Bongos colour into a fully-specified host build.
|
|
64
64
|
const COLOR_ROLES = {
|
|
65
|
-
bgCard: '#
|
|
66
|
-
rule: '#
|
|
67
|
-
accent: '#
|
|
65
|
+
bgCard: '#fbfafc', bgDeep: '#e2e1e4', ink: '#17181a',
|
|
66
|
+
rule: '#c6c6c8', ruleSoft: '#dcdbdd',
|
|
67
|
+
accent: '#fb9569', accentDeep: '#a3481a', terracotta: '#c9512c',
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// The pack, resolved exactly as gen-brand.js resolves it (env → instance → neutral).
|
|
@@ -33,9 +33,11 @@ const ASSUMED_BUILDER_MODEL = V4.assumed_builder_model || 'claude-fable-5';
|
|
|
33
33
|
const DEFAULT_GRADER_MODEL = V4.default_model || 'claude-sonnet-5';
|
|
34
34
|
const FALLTHROUGH_CONFIDENCE = V4.fallthrough_confidence ?? 0.3;
|
|
35
35
|
// task 1002660: per-worker model tier overrides (rubric-configured). The
|
|
36
|
-
// Quality worker was 41% of panel spend with 75% nit findings
|
|
37
|
-
//
|
|
38
|
-
//
|
|
36
|
+
// Quality worker was 41% of panel spend with 75% nit findings, so it ran on
|
|
37
|
+
// the haiku tier — until its 200k window overflowed on any big diff and the
|
|
38
|
+
// lens went dark (task 1003318: now claude-sonnet-5, a floor that coincides
|
|
39
|
+
// with default_model for top-tier builders). Keys are worker kinds; values are
|
|
40
|
+
// model ids. workerModelFor guards the cross-model invariant.
|
|
39
41
|
const WORKER_MODEL_TIERS = V4.worker_model_tiers || {};
|
|
40
42
|
const workers = require('./grader-workers');
|
|
41
43
|
const generatedProvenance = require('./generated-provenance'); // task 1002795
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"assumed_builder_model": "claude-fable-5",
|
|
13
13
|
"model_refresh_note": "task 1002659 (2026-08-11): pins refreshed to the Claude 5 family. Assumed builder = claude-fable-5 (the owner-top-model default per CLAUDE.md §2); default grader = claude-sonnet-5 (cross-model per ADR 0024, cost-parity with the prior sonnet-4-6 posture — opus-5 grades the sonnet/haiku builders where the grader should be the stronger model). selectGraderModel no longer throws on an unknown builder id: it warns loudly and falls back to default_model (the #117 throw stranded ships whose builder id lacked an opus/sonnet/haiku substring — exactly what claude-fable-5 is).",
|
|
14
14
|
"active_panel": ["narc", "quality", "hacker", "efficiency"],
|
|
15
|
-
"worker_model_tiers": { "quality": "claude-
|
|
16
|
-
"worker_model_tiers_note": "task 1002660: per-worker cost tiering. Quality was 41% of panel spend with 75% nit findings — its cq/economy lens
|
|
15
|
+
"worker_model_tiers": { "quality": "claude-sonnet-5" },
|
|
16
|
+
"worker_model_tiers_note": "task 1002660: per-worker cost tiering. Quality was 41% of panel spend with 75% nit findings — its cq/economy lens ran on the haiku tier. task 1003318: moved to claude-sonnet-5 — haiku 4.5's 200k window overflows on any diff over ~150 KB (`Prompt is too long`, deterministic; tasks 1003297 and 1003298 each lost three ~$5 panel runs to it) and a Quality worker that never starts is missing signal on a GATING lens. For fable/opus builders the panel model is already claude-sonnet-5, so the tier coincides with default_model and acts as a floor — a future default_model bump must not pin Quality back onto a smaller window; it stays a live cost lever only for haiku builders (whose panel runs on opus-5). workerModelFor refuses an override that lands on the builder's own model family (the ADR 0024 cross-model guarantee outranks the cost lever); gate semantics unchanged — Quality's verdict still gates identically.",
|
|
17
17
|
"fallthrough_confidence": 0.3,
|
|
18
18
|
"low_confidence_threshold": 0.4,
|
|
19
19
|
"rationale": "GDS-V3 task #410 (MAS Phase 2.0), 2026-05-29. Supersedes v3 (single-prompt 3-shot generalist). Phase 1 calibration showed minimal between-shot disagreement on the same prompt — the strict gate fired correctly but the diversity signal was weak. v4 trades sampling-variance for lens-specialization: replace 3 identical-prompt shots with N workers (each a distinct prompt focused on one axis). Phase 2.0 ships 2 of the 3 planned workers (narc for completion, quality for cq + advisory economy) — keeps the gate at the same strictness while the framework calibrates. Phase 2.1 adds hacker (security; wraps /builder-redteam as a CI gate). Phase 2.2 adds efficiency_monger.",
|
|
@@ -19,18 +19,23 @@ function isNum(n) {
|
|
|
19
19
|
return Number.isFinite(n);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// #1002653 corroboration helpers for validateAndScore's null-
|
|
23
|
-
//
|
|
24
|
-
// on an errored worker is the normal
|
|
25
|
-
// NON-ARRAY issues is malformed and
|
|
26
|
-
// schema_error downstream), never
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
// #1002653 / task 1003318 corroboration helpers for validateAndScore's null-axis
|
|
23
|
+
// lens branches (Narc → ff, Quality → cq). A worker entry is untrusted input —
|
|
24
|
+
// w.issues may be any shape. Absent issues on an errored worker is the normal
|
|
25
|
+
// outage shape (treated as none); a truthy NON-ARRAY issues is malformed and
|
|
26
|
+
// must DISQUALIFY corroboration (fail-closed schema_error downstream), never
|
|
27
|
+
// TypeError into a 500 on grade submission.
|
|
28
|
+
const isWorkerErroredClean = (kind) => (w) => {
|
|
29
|
+
if (!w || w.kind !== kind || !w.error) return false;
|
|
29
30
|
const issues = w.issues == null ? [] : w.issues;
|
|
30
31
|
if (!Array.isArray(issues)) return false;
|
|
31
32
|
return !issues.some((i) => i && (i.severity === 'blocker' || i.severity === 'major'));
|
|
32
33
|
};
|
|
33
|
-
const
|
|
34
|
+
const isWorkerHealthy = (kind) => (w) => !!w && w.kind === kind && !w.error;
|
|
35
|
+
const isNarcErroredClean = isWorkerErroredClean('narc');
|
|
36
|
+
const isNarcHealthy = isWorkerHealthy('narc');
|
|
37
|
+
const isQualityErroredClean = isWorkerErroredClean('quality');
|
|
38
|
+
const isQualityHealthy = isWorkerHealthy('quality');
|
|
34
39
|
|
|
35
40
|
// task 1002658 (ADR 0164): a SUBSTANTIVE issue is one a real panel emits — a
|
|
36
41
|
// known severity + a non-empty summary. The old plausibility guard counted raw
|
|
@@ -95,8 +100,8 @@ function validateAndScore(rawSubagent, meta = {}) {
|
|
|
95
100
|
// needs POSITIVE corroboration: workers[] carries an errored
|
|
96
101
|
// no-substantive-finding Narc (#473 missing-signal semantics) and no healthy
|
|
97
102
|
// Narc. Empty/narc-less/absent workers, ABSENT ff, and every other shape
|
|
98
|
-
// fall through to the fail-closed schema_error below. Quality
|
|
99
|
-
//
|
|
103
|
+
// fall through to the fail-closed schema_error below. Quality's twin branch
|
|
104
|
+
// (task 1003318, below) is gating, so it never passes.
|
|
100
105
|
// Trust note: workers[] is client-supplied like every SR-9 grade input — a
|
|
101
106
|
// forger gains nothing here they cannot get by sending ff:9 directly; the
|
|
102
107
|
// server-derivable-signals redesign is tracked separately (SR-9 residual).
|
|
@@ -105,8 +110,23 @@ function validateAndScore(rawSubagent, meta = {}) {
|
|
|
105
110
|
metaWorkers.some(isNarcErroredClean) && !metaWorkers.some(isNarcHealthy);
|
|
106
111
|
const ffExplicitNull = parsed.functional_fidelity === null;
|
|
107
112
|
const ffLensUnavailable = ffExplicitNull && narcMissingSignal;
|
|
113
|
+
// task 1003318: the same shape for the GATING Quality lens. The haiku-tier
|
|
114
|
+
// Quality worker died on a context-window overflow (`Prompt is too long`)
|
|
115
|
+
// before it started; aggregatePanel forwarded code_quality: null and
|
|
116
|
+
// Number(null) === 0 fabricated "FAIL — code_quality below 6" at (9+0)/2.
|
|
117
|
+
// Unlike the advisory ff branch this NEVER passes: a gating lens that did not
|
|
118
|
+
// run is recorded as unavailable (json-null axis, score on the axis that ran,
|
|
119
|
+
// signals.cq_lens_unavailable) and the task parks at completed for
|
|
120
|
+
// manual-confirm — fail-closed, and a forger gains nothing they could not get
|
|
121
|
+
// by sending cq:9 outright. Same corroboration: an errored no-finding Quality
|
|
122
|
+
// in workers[] and no healthy one; every other null shape is schema_error.
|
|
123
|
+
const qualityMissingSignal = !!metaWorkers &&
|
|
124
|
+
metaWorkers.some(isQualityErroredClean) && !metaWorkers.some(isQualityHealthy);
|
|
125
|
+
const cqExplicitNull = parsed.code_quality === null;
|
|
126
|
+
const cqLensUnavailable = cqExplicitNull && qualityMissingSignal;
|
|
127
|
+
const qualityErrorTag = cqLensUnavailable ? String(metaWorkers.find(isQualityErroredClean).error) : null;
|
|
108
128
|
const ff = ffExplicitNull ? null : Number(parsed.functional_fidelity);
|
|
109
|
-
const cq = Number(parsed.code_quality);
|
|
129
|
+
const cq = cqExplicitNull ? null : Number(parsed.code_quality);
|
|
110
130
|
const economyRaw = Number(parsed.economy);
|
|
111
131
|
const economy =
|
|
112
132
|
isNum(economyRaw) && economyRaw >= 0 && economyRaw <= 10 ? economyRaw : null;
|
|
@@ -138,9 +158,13 @@ function validateAndScore(rawSubagent, meta = {}) {
|
|
|
138
158
|
|
|
139
159
|
signals.confidence = confidence;
|
|
140
160
|
signals.issue_count = issues.length;
|
|
141
|
-
|
|
161
|
+
// Set AND cleared: `signals` spreads the client's own blob, so a forged
|
|
162
|
+
// `*_lens_unavailable: true` on a judged grade must not survive into the row
|
|
163
|
+
// (the ship card keys its outage reading on these).
|
|
164
|
+
if (ffLensUnavailable) signals.ff_lens_unavailable = true; else delete signals.ff_lens_unavailable;
|
|
165
|
+
if (cqLensUnavailable) signals.cq_lens_unavailable = true; else delete signals.cq_lens_unavailable;
|
|
142
166
|
|
|
143
|
-
if ((!ffLensUnavailable && (!isNum(ff) || ff < 0 || ff > 10)) || !isNum(cq) || cq < 0 || cq > 10) {
|
|
167
|
+
if ((!ffLensUnavailable && (!isNum(ff) || ff < 0 || ff > 10)) || (!cqLensUnavailable && (!isNum(cq) || cq < 0 || cq > 10))) {
|
|
144
168
|
return {
|
|
145
169
|
score: 0,
|
|
146
170
|
passed: false,
|
|
@@ -152,22 +176,34 @@ function validateAndScore(rawSubagent, meta = {}) {
|
|
|
152
176
|
notes_md: `Subagent grader ${VERSION}: subagent returned scores outside [0,10] or non-numeric. Got functional_fidelity=${parsed.functional_fidelity}, code_quality=${parsed.code_quality}.`
|
|
153
177
|
+ (ffExplicitNull && !narcMissingSignal
|
|
154
178
|
? ' Explicit null functional_fidelity without a corroborated Narc outage in signals.workers is fail-closed.'
|
|
179
|
+
: '')
|
|
180
|
+
+ (cqExplicitNull && !qualityMissingSignal
|
|
181
|
+
? ' Explicit null code_quality without a corroborated Quality outage in signals.workers is fail-closed.'
|
|
155
182
|
: ''),
|
|
156
183
|
issues,
|
|
157
184
|
};
|
|
158
185
|
}
|
|
159
186
|
|
|
160
187
|
const ffR = ffLensUnavailable ? null : r1(clamp(ff, 0, 10));
|
|
161
|
-
const cqR = r1(clamp(cq, 0, 10));
|
|
188
|
+
const cqR = cqLensUnavailable ? null : r1(clamp(cq, 0, 10));
|
|
162
189
|
const economyR = economy != null ? r1(clamp(economy, 0, 10)) : null;
|
|
163
190
|
const securityR = securityScore != null ? r1(clamp(securityScore, 0, 10)) : null;
|
|
164
191
|
const efficiencyR = efficiencyScore != null ? r1(clamp(efficiencyScore, 0, 10)) : null;
|
|
165
192
|
const economyPenalty =
|
|
166
193
|
economyR != null ? Math.max(0, (THRESHOLD - economyR) / 2) : 0;
|
|
167
|
-
const cqEffective =
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
194
|
+
const cqEffective = cqLensUnavailable
|
|
195
|
+
? null
|
|
196
|
+
: economyR != null ? r1(clamp(cqR - economyPenalty, 0, 10)) : cqR;
|
|
197
|
+
// With a lens out, the score reflects only the axis that ran — never a blend
|
|
198
|
+
// with a synthetic 0 (the fabricated 4.5/10) or a synthetic threshold. Both
|
|
199
|
+
// out → 0: nothing was judged.
|
|
200
|
+
const blended = ffLensUnavailable && cqLensUnavailable
|
|
201
|
+
? 0
|
|
202
|
+
: ffLensUnavailable
|
|
203
|
+
? cqR
|
|
204
|
+
: cqLensUnavailable
|
|
205
|
+
? ffR
|
|
206
|
+
: r1((ffR + cqR) / 2);
|
|
171
207
|
|
|
172
208
|
// confidence must be present (not null) for a PASS. A subagent that omits
|
|
173
209
|
// confidence entirely silently bypassed the low-confidence gate under the
|
|
@@ -182,26 +218,40 @@ function validateAndScore(rawSubagent, meta = {}) {
|
|
|
182
218
|
// (null < THRESHOLD is true via JS coercion), and must not appear in the
|
|
183
219
|
// verdict's below-threshold branches.
|
|
184
220
|
const ffBelow = !ffLensUnavailable && ffR < THRESHOLD;
|
|
185
|
-
const
|
|
186
|
-
const
|
|
187
|
-
|
|
221
|
+
const cqBelow = !cqLensUnavailable && cqR < THRESHOLD;
|
|
222
|
+
const bothPass = !ffBelow && !cqBelow;
|
|
223
|
+
// A GATING lens that did not run is never a PASS (ff is advisory since #481;
|
|
224
|
+
// cq is not) — manual-confirm is the only way past it (task 1003318).
|
|
225
|
+
const passed = bothPass && !lowConfidence && !confidenceAbsent && !cqLensUnavailable;
|
|
226
|
+
|
|
227
|
+
// The UNAVAILABLE reading is only honest when the lenses that DID run found
|
|
228
|
+
// nothing substantive: a Hacker blocker beside a dead Quality is a rejection
|
|
229
|
+
// with a missing axis, not an outage, and must keep the ordinary FAIL chain
|
|
230
|
+
// (the #574 posture — a dark lens hardens the outcome, never softens it).
|
|
231
|
+
const hasSubstantiveFinding = issues.some((i) => i.severity === 'blocker' || i.severity === 'major');
|
|
188
232
|
const verdict = passed
|
|
189
233
|
? 'PASS'
|
|
190
|
-
:
|
|
191
|
-
?
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
234
|
+
: cqLensUnavailable && !hasSubstantiveFinding
|
|
235
|
+
? `UNAVAILABLE — the code_quality lens did not run (Quality worker errored: ${qualityErrorTag}); not a quality rejection — manual-confirm available`
|
|
236
|
+
+ (ffBelow ? ` (functional_fidelity below ${THRESHOLD})` : '')
|
|
237
|
+
// the confidence reasons the chain below would have named — kept as a
|
|
238
|
+
// tail so the #489 gate-walk signal is never hidden by the outage line
|
|
239
|
+
+ (confidenceAbsent ? '; confidence absent' : lowConfidence ? `; low confidence ${confidence}` : '')
|
|
240
|
+
: confidenceAbsent
|
|
241
|
+
? 'FAIL — confidence absent'
|
|
242
|
+
: lowConfidence
|
|
243
|
+
? 'FAIL — low confidence'
|
|
244
|
+
: bothPass
|
|
245
|
+
? 'FAIL'
|
|
246
|
+
: ffBelow && cqBelow
|
|
247
|
+
? `FAIL — both axes below ${THRESHOLD}`
|
|
248
|
+
: ffBelow
|
|
249
|
+
? `FAIL — functional_fidelity below ${THRESHOLD}`
|
|
250
|
+
: `FAIL — code_quality below ${THRESHOLD}`;
|
|
201
251
|
|
|
202
252
|
const notesLines = [];
|
|
203
253
|
notesLines.push(`Shot ${signals.shot_index != null ? signals.shot_index : '?'} (${signals.model}) — ${verdict}`);
|
|
204
|
-
notesLines.push(` ff=${ffLensUnavailable ? 'n/a (lens unavailable)' : `${ffR}/10`} cq=${cqR}/10${economyR != null ? ` econ=${economyR}/10 (advisory)` : ''} conf=${confidence ?? '?'}`);
|
|
254
|
+
notesLines.push(` ff=${ffLensUnavailable ? 'n/a (lens unavailable)' : `${ffR}/10`} cq=${cqLensUnavailable ? 'n/a (lens unavailable)' : `${cqR}/10`}${economyR != null ? ` econ=${economyR}/10 (advisory)` : ''} conf=${confidence ?? '?'}`);
|
|
205
255
|
if (notesFromSubagent) {
|
|
206
256
|
notesLines.push('');
|
|
207
257
|
notesLines.push(notesFromSubagent.trim());
|
|
@@ -559,6 +609,9 @@ function aggregateShots(shotResults, meta = {}) {
|
|
|
559
609
|
const cq = median(verdicts.map((v) => v.cq));
|
|
560
610
|
const economy = median(verdicts.map((v) => v.economy));
|
|
561
611
|
const cqEffective = median(verdicts.map((v) => v.cq_effective));
|
|
612
|
+
// NB (task 1003318): this v3 multi-shot path still collapses a null axis to
|
|
613
|
+
// 0 — it serves the trivial-diff single shot, which cannot overflow a window;
|
|
614
|
+
// the panel path's lens-outage handling lives in validateAndScore.
|
|
562
615
|
const blended = ff != null && cq != null ? r1((ff + cq) / 2) : 0;
|
|
563
616
|
// Top-level aggregated confidence = median of per-shot confidences. Without
|
|
564
617
|
// this, ship.js forwards a null top-level confidence to /tasks/:id/grade,
|
|
@@ -45,6 +45,17 @@ const TRANSIENT_WORKER_ERRORS = new Set([
|
|
|
45
45
|
'SUBAGENT_NONZERO_EXIT',
|
|
46
46
|
]);
|
|
47
47
|
|
|
48
|
+
// task 1003318: a context-window overflow is NOT transient. The CLI refuses the
|
|
49
|
+
// request before the worker starts (`Prompt is too long: the request is ~251248
|
|
50
|
+
// tokens (limit 200000)`) and refuses the retry identically, so the #465 retry
|
|
51
|
+
// only burns another round. Its own tag names the cause on the grade row and
|
|
52
|
+
// in the server's verdict line (grader-score.js keys the lens outage on ANY
|
|
53
|
+
// errored no-finding Quality — the tag is the diagnosis, not the trigger).
|
|
54
|
+
// The pattern is the API's exact sentence, so a diff that merely mentions the
|
|
55
|
+
// phrase cannot trip it.
|
|
56
|
+
const PROMPT_TOO_LONG_RE = /prompt is too long: the request is ~?\d+ tokens/i;
|
|
57
|
+
const PROMPT_TOO_LONG = 'PROMPT_TOO_LONG';
|
|
58
|
+
|
|
48
59
|
// #467: per-worker subagent timeout. The global 240s applied to EVERY worker,
|
|
49
60
|
// which timed out the Read-heavy ones (Narc walks ACs + reads files — hence
|
|
50
61
|
// Phase 2.0.5's 5-read workaround; Quality is next-heaviest). Per-worker budgets
|
|
@@ -176,6 +187,14 @@ async function runWorker(worker, { task, valueSummary, diff, changedFiles, diffS
|
|
|
176
187
|
// (`claude` prints its "not logged in" line there) — fall back so the tail
|
|
177
188
|
// is never empty when the subprocess did explain itself.
|
|
178
189
|
stderrTail = redactStderrTail(err.stderr) ?? redactStderrTail(err.stdout);
|
|
190
|
+
// Matched on the RAW stream (the redacted tail keeps only the last 400
|
|
191
|
+
// chars), stderr first and stdout only when stderr is silent — stdout
|
|
192
|
+
// carries the model's own text. A SUBAGENT_TIMEOUT keeps its tag: it is
|
|
193
|
+
// the #467 budget signal, never a refusal.
|
|
194
|
+
if (err.code !== 'SUBAGENT_TIMEOUT') {
|
|
195
|
+
const said = String(err.stderr || '').trim() || String(err.stdout || '');
|
|
196
|
+
if (PROMPT_TOO_LONG_RE.test(said)) subprocessError = PROMPT_TOO_LONG;
|
|
197
|
+
}
|
|
179
198
|
}
|
|
180
199
|
const parsed = subprocessError
|
|
181
200
|
? null
|
|
@@ -550,17 +550,22 @@
|
|
|
550
550
|
// A grader OUTAGE row (panel_outcome 'unavailable') carries a placeholder
|
|
551
551
|
// score of 0 — label it, never render it as a 0.0 fail (task 1002652).
|
|
552
552
|
const isOutage = g.panel_outcome === 'unavailable';
|
|
553
|
-
|
|
553
|
+
// A json-null gating axis (task 1003318 — the Quality worker never ran)
|
|
554
|
+
// is likewise not a judgment: the score is the surviving axis, not a fail.
|
|
555
|
+
const isLensOut = !isOutage && !!g.rubric_scores && g.rubric_scores.code_quality === null;
|
|
556
|
+
const score = isOutage || isLensOut ? '—' : Number(g.score).toFixed(1);
|
|
554
557
|
const verdict = isOutage
|
|
555
558
|
? `<span style="color:var(--ink-soft,#8a8577)">not graded (grader outage)</span>`
|
|
556
|
-
:
|
|
559
|
+
: isLensOut
|
|
560
|
+
? `<span style="color:var(--ink-soft,#8a8577)">not graded (quality lens unavailable)</span>`
|
|
561
|
+
: g.passed
|
|
557
562
|
? `<span style="color:var(--olive,#5b7a4d);font-weight:600">passed</span>`
|
|
558
563
|
: `<span style="color:#a04040;font-weight:600">fell short</span>`;
|
|
559
564
|
return `
|
|
560
565
|
<tr>
|
|
561
566
|
<td class="ledger__num">#${g.task_id}</td>
|
|
562
567
|
<td>${escapeHtml(g.title || '')}</td>
|
|
563
|
-
<td class="ledger__drachmae">${isOutage ? '—' : `${score} / 10`}</td>
|
|
568
|
+
<td class="ledger__drachmae">${isOutage || isLensOut ? '—' : `${score} / 10`}</td>
|
|
564
569
|
<td>${verdict}</td>
|
|
565
570
|
<td class="ledger__date">${fmtDate(g.graded_at)}</td>
|
|
566
571
|
</tr>
|
|
@@ -99,8 +99,8 @@ function esc(s) {
|
|
|
99
99
|
const ACCENT = (() => {
|
|
100
100
|
try {
|
|
101
101
|
const c = api.branding().theme?.ui?.colors || {};
|
|
102
|
-
return { sun: c.accent || '#
|
|
103
|
-
} catch { return { sun: '#
|
|
102
|
+
return { sun: c.accent || '#fb9569', sun600: c.accentDeep || '#a3481a' };
|
|
103
|
+
} catch { return { sun: '#fb9569', sun600: '#a3481a' }; }
|
|
104
104
|
})();
|
|
105
105
|
|
|
106
106
|
// Brand styling for the standalone onboarding pages — sunrise palette + Baloo 2 /
|
|
@@ -108,7 +108,7 @@ const ACCENT = (() => {
|
|
|
108
108
|
// under the instance's own config/branding.json). Light + dark aware; no external
|
|
109
109
|
// dependency beyond an optional Google-Fonts link (system fallback if it doesn't load).
|
|
110
110
|
const PAGE_STYLE = `
|
|
111
|
-
:root{color-scheme:light dark;--sun:${ACCENT.sun};--sun600:${ACCENT.sun600};--coral:#fb7185;--sky:#38bdf8;--sky600:#0284c7;--ok:#16a34a;--warn:#f59e0b;--ink:#2a1f17;--inkSoft:#6b5d52;--card:#fffdfa;--line:#f0e2cf;--bg1:#fde8c8;--bg2:#fff4e6;--bg3:#fffdfa}
|
|
111
|
+
:root{color-scheme:light dark;--sun:${ACCENT.sun};--sun600:${ACCENT.sun600};--sunInk:#2a1305;--coral:#fb7185;--sky:#38bdf8;--sky600:#0284c7;--ok:#16a34a;--warn:#f59e0b;--ink:#2a1f17;--inkSoft:#6b5d52;--card:#fffdfa;--line:#f0e2cf;--bg1:#fde8c8;--bg2:#fff4e6;--bg3:#fffdfa}
|
|
112
112
|
@media (prefers-color-scheme:dark){:root{--ink:#f5efe6;--inkSoft:#cbbdad;--card:#241b13;--line:#3a2c1e;--bg1:#2a1d10;--bg2:#1b130b;--bg3:#130d07}}
|
|
113
113
|
*{box-sizing:border-box}html,body{height:100%}
|
|
114
114
|
body{margin:0;font-family:"Quicksand",system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--ink);background:linear-gradient(180deg,var(--bg1) 0%,var(--bg2) 45%,var(--bg3) 100%);background-attachment:fixed;display:flex;align-items:center;justify-content:center;padding:1.5rem;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
|
|
@@ -135,7 +135,7 @@ code{font-family:"Fira Code",ui-monospace,SFMono-Regular,monospace;background:rg
|
|
|
135
135
|
@media (prefers-reduced-motion:reduce){.step.active .dot,.step.active .dot::after{animation:none}}
|
|
136
136
|
.status-line{min-height:1.4em;color:var(--inkSoft);font-size:.94rem;margin:.4rem auto 0;max-width:24rem;line-height:1.45}
|
|
137
137
|
.cta{margin-top:1.4rem}
|
|
138
|
-
.btn{display:inline-block;background:var(--sun);color
|
|
138
|
+
.btn{display:inline-block;background:var(--sun);color:var(--sunInk);text-decoration:none;font-weight:700;font-family:"Baloo 2",system-ui,sans-serif;padding:.72rem 1.5rem;border-radius:999px;font-size:1.02rem;box-shadow:0 10px 22px -8px rgba(249,115,22,.7);transition:transform .15s ease,box-shadow .15s ease}
|
|
139
139
|
.btn:hover{transform:translateY(-1px);box-shadow:0 14px 28px -8px rgba(249,115,22,.8)}
|
|
140
140
|
.muted{color:var(--inkSoft);opacity:.9;font-size:.85rem;margin:1.1rem auto 0;max-width:24rem;line-height:1.45}
|
|
141
141
|
.hidden{display:none!important}
|
|
@@ -8,14 +8,19 @@
|
|
|
8
8
|
/* Self-contained so the showcase renders correctly whether or not the host
|
|
9
9
|
injects theme tokens. Warm Cloud Bongos defaults; overridable by the pack. */
|
|
10
10
|
:root {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/* a hand-written mirror of config/branding.neutral.json theme.ui.colors —
|
|
12
|
+
this page is served without the branding injection, so a drifted value
|
|
13
|
+
renders a palette the product no longer paints (tests/design_tokens_sync.mjs).
|
|
14
|
+
Chrome world, task 1003298. --accent-deep is the TEXT-safe accent: the
|
|
15
|
+
salmon --accent is a fill and measures 2.1:1 as type on the card. */
|
|
16
|
+
--bg: #edecee; --card: #fbfafc; --ink: #17181a; --ink-soft: #55565a;
|
|
17
|
+
--rule: #c6c6c8; --accent: #fb9569; --accent-deep: #a3481a;
|
|
13
18
|
}
|
|
14
19
|
* { box-sizing: border-box; }
|
|
15
20
|
body {
|
|
16
21
|
margin: 0; padding: 2.5rem 1.25rem 4rem;
|
|
17
22
|
background: var(--bg); color: var(--ink);
|
|
18
|
-
font-family: "
|
|
23
|
+
font-family: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
19
24
|
line-height: 1.5;
|
|
20
25
|
}
|
|
21
26
|
.wrap { max-width: 960px; margin: 0 auto; }
|
|
@@ -28,14 +33,15 @@
|
|
|
28
33
|
padding: 1.1rem 1.2rem; text-decoration: none; color: inherit;
|
|
29
34
|
display: flex; flex-direction: column; gap: .4rem; transition: transform .12s ease, box-shadow .12s ease;
|
|
30
35
|
}
|
|
31
|
-
.card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(
|
|
36
|
+
.card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,.12); }
|
|
32
37
|
.card h2 { font-size: 1.15rem; margin: 0; }
|
|
33
38
|
.card p { margin: 0; color: var(--ink-soft); font-size: .95rem; }
|
|
34
|
-
.card .origin { color: var(--accent); font-size: .82rem; word-break: break-all; margin-top: auto; }
|
|
39
|
+
.card .origin { color: var(--accent-deep); font-size: .82rem; word-break: break-all; margin-top: auto; }
|
|
35
40
|
.card .art { width: 100%; height: 120px; object-fit: cover; border-radius: 10px; margin-bottom: .3rem; }
|
|
36
41
|
.empty, .err { text-align: center; color: var(--ink-soft); padding: 3rem 1rem; }
|
|
37
42
|
@media (prefers-color-scheme: dark) {
|
|
38
|
-
:root { --bg: #
|
|
43
|
+
:root { --bg: #000000; --card: #101012; --ink: #ffffff; --ink-soft: #c0c0c0; --rule: rgba(255,255,255,.16);
|
|
44
|
+
--accent-deep: color-mix(in srgb, var(--accent) 45%, #ffffff); }
|
|
39
45
|
}
|
|
40
46
|
</style>
|
|
41
47
|
</head>
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.389",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.389",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.389",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|