@bongos/core 1.19.784 → 1.19.786
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 +13 -13
- package/.claude/skills/planning-session/SKILL.md +4 -0
- package/docs/module-api-changelog.md +4 -0
- package/docs/packs/ideator.md +6 -0
- package/modules/security/secret-scrub.js +23 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/scrubber_corpus.mjs +59 -0
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.786",
|
|
6
|
+
"core_contract": "1.19.786",
|
|
7
|
+
"source_commit": "785c921afb48af049814782f27929cc27885667c",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-16T22:20:27.767Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 483,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 2668,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "3d454ef4a876f5368603708cbe4f13b53dc57a854dc03e217285b327b6dd0bf9",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
{
|
|
208
208
|
"path": ".claude/skills/planning-session/SKILL.md",
|
|
209
209
|
"mode": "0000644",
|
|
210
|
-
"sha256": "
|
|
210
|
+
"sha256": "8ed3e62213268015e49ad180d9f9c0c3c875867b392e93430a9850962a70455b"
|
|
211
211
|
},
|
|
212
212
|
{
|
|
213
213
|
"path": ".claude/skills/priority-session/SKILL.md",
|
|
@@ -2512,7 +2512,7 @@
|
|
|
2512
2512
|
{
|
|
2513
2513
|
"path": "docs/module-api-changelog.md",
|
|
2514
2514
|
"mode": "0000644",
|
|
2515
|
-
"sha256": "
|
|
2515
|
+
"sha256": "580f9ae0d3677bc11fe335f73027c314edd8633f2397cd71400e07725a8f4a03"
|
|
2516
2516
|
},
|
|
2517
2517
|
{
|
|
2518
2518
|
"path": "docs/modules-contract.md",
|
|
@@ -2597,7 +2597,7 @@
|
|
|
2597
2597
|
{
|
|
2598
2598
|
"path": "docs/packs/ideator.md",
|
|
2599
2599
|
"mode": "0000644",
|
|
2600
|
-
"sha256": "
|
|
2600
|
+
"sha256": "93cef9d530a668d750d6cba4789fda25b15d176c35366240cb72187e272fa141"
|
|
2601
2601
|
},
|
|
2602
2602
|
{
|
|
2603
2603
|
"path": "docs/project-context.template.md",
|
|
@@ -7062,7 +7062,7 @@
|
|
|
7062
7062
|
{
|
|
7063
7063
|
"path": "modules/security/secret-scrub.js",
|
|
7064
7064
|
"mode": "0000644",
|
|
7065
|
-
"sha256": "
|
|
7065
|
+
"sha256": "c28b9a47e3d01d206cb2a13e71844865a95cc2a9dc5e0237e1153ccf8f292286"
|
|
7066
7066
|
},
|
|
7067
7067
|
{
|
|
7068
7068
|
"path": "modules/security/security.js",
|
|
@@ -7622,12 +7622,12 @@
|
|
|
7622
7622
|
{
|
|
7623
7623
|
"path": "package-lock.json",
|
|
7624
7624
|
"mode": "0000644",
|
|
7625
|
-
"sha256": "
|
|
7625
|
+
"sha256": "a08e66b825d352b3b0c128f3b5b71d4665183bf734d69d0e837adf8946a28f19"
|
|
7626
7626
|
},
|
|
7627
7627
|
{
|
|
7628
7628
|
"path": "package.json",
|
|
7629
7629
|
"mode": "0000644",
|
|
7630
|
-
"sha256": "
|
|
7630
|
+
"sha256": "9f9dfe9f5f8cc3d3ebc1cd46909eb73ac9ef03046933478f391cb6c23680cfa6"
|
|
7631
7631
|
},
|
|
7632
7632
|
{
|
|
7633
7633
|
"path": "public-docs/index.html",
|
|
@@ -9492,7 +9492,7 @@
|
|
|
9492
9492
|
{
|
|
9493
9493
|
"path": "src/module-api.js",
|
|
9494
9494
|
"mode": "0000644",
|
|
9495
|
-
"sha256": "
|
|
9495
|
+
"sha256": "0eb65d596ccf4f9af9cb2ec8769e373c18f3148b93e785157895d4dbb94299c7"
|
|
9496
9496
|
},
|
|
9497
9497
|
{
|
|
9498
9498
|
"path": "src/module-loader/catalog.js",
|
|
@@ -12557,7 +12557,7 @@
|
|
|
12557
12557
|
{
|
|
12558
12558
|
"path": "tests/scrubber_corpus.mjs",
|
|
12559
12559
|
"mode": "0000644",
|
|
12560
|
-
"sha256": "
|
|
12560
|
+
"sha256": "d1f80894bd96f866359d3d1997e36e8843fe3dba141ac621874cdc1d530b9282"
|
|
12561
12561
|
},
|
|
12562
12562
|
{
|
|
12563
12563
|
"path": "tests/seam_wiring_guard.mjs",
|
|
@@ -15,6 +15,10 @@ The first planning session — V3 Planning Session #1, 2026-05-12 — is the tem
|
|
|
15
15
|
- A version is in `status='planning'` and needs scope locked before tasks start landing in earnest
|
|
16
16
|
- A previous planning session left proposals in `idea_inbox` tagged `kind='criterion-proposal'` that need ratification
|
|
17
17
|
|
|
18
|
+
**Run an ideation pass first when the goal's SHAPE is not yet settled.** An ideator session (the [Ideator pack](../../../docs/packs/ideator.md)) inverts this skill's stance: there the human drives and you are the sounding board, so *their* framing sets the shape of the thing. Carry its output into Phase 1 and the Phase-4 interview is left with genuine residue instead of first-pass design.
|
|
19
|
+
|
|
20
|
+
Not a gate — a session for work whose shape is already settled should open directly. But **Phase 4 is a poor instrument for a first pass**: an `AskUserQuestion` round must author its options before the owner has said anything, so every option encodes *your* framing, and a proposal you believe is correct never becomes a question at all. The 2026-08-16 Board Room session is the evidence — three agent proposals (a role-based voting chamber, a tiered standard-of-review override ledger, Discord reaction-voting) died in the ideation half that would otherwise have been baked into the spec as defaults, none of which would have surfaced as an interview question.
|
|
21
|
+
|
|
18
22
|
## When NOT to invoke
|
|
19
23
|
|
|
20
24
|
- Mid-version: planning sessions set scope, they don't refine it. For mid-version adjustments, use `/idea-triage`.
|
|
@@ -2042,5 +2042,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2042
2042
|
landed since 1.19.782 with no explicit bump. run 35152631705. (task 1002620)
|
|
2043
2043
|
1.19.784 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2044
2044
|
landed since 1.19.783 with no explicit bump. run 35155326585. (task 1002620)
|
|
2045
|
+
1.19.785 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2046
|
+
landed since 1.19.784 with no explicit bump. run 35156349018. (task 1002620)
|
|
2047
|
+
1.19.786 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2048
|
+
landed since 1.19.785 with no explicit bump. run 35157132070. (task 1002620)
|
|
2045
2049
|
---------------------------------------------------------------------------
|
|
2046
2050
|
```
|
package/docs/packs/ideator.md
CHANGED
|
@@ -101,6 +101,12 @@ That is the **same route** the hall form uses, so the record is identical — sa
|
|
|
101
101
|
|
|
102
102
|
The command reports what the server **stored**. If it says the idea landed as *quick*, say so plainly — capture is fail-open on grading, and telling someone they filed a Full Idea when they did not is the one outcome worse than the failure itself.
|
|
103
103
|
|
|
104
|
+
### When the thread is bigger than one idea
|
|
105
|
+
|
|
106
|
+
Some developed threads are not an idea — they are the shape of a whole goal or version: several interlocking pieces, a scope someone would have to *plan* rather than just build. When that is what you are looking at, **say so and offer the handoff to `/planning-session`**, which turns a settled shape into criteria, a written spec and a seeded task list. Arriving there with the shape already agreed is the point: its interview is then about residue, not about inventing the thing.
|
|
107
|
+
|
|
108
|
+
File the idea first either way, and treat the handoff as an offer rather than a gate — a thread they would rather leave as an idea stays one. Planning is a trusted-builder step, so if they cannot open one themselves, the filed idea *is* the handoff: it queues for whoever runs the next session.
|
|
109
|
+
|
|
104
110
|
### Developing someone else's spark
|
|
105
111
|
|
|
106
112
|
The same conversation works on a **Big Idea Spark** — a quick idea whose author marked it as needing development. `node scripts/gds/spark.js --list` shows what is waiting; develop one with `spark.js --develop <id> --fields-file <path>`. The author keeps the credit for having had the thought and the payout splits with them (ADR 0185), so the never-invent rule applies with *more* force, not less: those five answers go out under two people's names.
|
|
@@ -190,12 +190,34 @@ const ENV_SECRET_PREFIX_RE = /^(?:gds_|pms_|mac_|apple|anthropic|stripe|cf_|clou
|
|
|
190
190
|
// last `cd` (task 2130). Exact-match only, so real password vars (MYSQL_PWD, DB_PWD, …)
|
|
191
191
|
// still match below.
|
|
192
192
|
const ENV_BENIGN_KEY_RE = /^(?:PWD|OLDPWD)$/;
|
|
193
|
+
// CONFIG-IDENTIFIER NAMES under a provider prefix (task 1003512). ENV_SECRET_PREFIX_RE
|
|
194
|
+
// matches ^anthropic, so the Claude Code harness's own ANTHROPIC_DEFAULT_OPUS_MODEL —
|
|
195
|
+
// whose value is a MODEL ID like claude-opus-5, not a credential — was collected as a
|
|
196
|
+
// live secret. package-core's fail-closed leak gate then flagged every functional file
|
|
197
|
+
// containing that string verbatim and refused to build, on ANY machine where Claude
|
|
198
|
+
// Code had set its model vars, i.e. every builder machine. Hit live packaging
|
|
199
|
+
// 1.19.209; the workaround was `env -u ANTHROPIC_DEFAULT_OPUS_MODEL`.
|
|
200
|
+
//
|
|
201
|
+
// AN ALLOWLIST ON THE NAME, NOT A SHAPE TEST ON THE VALUE. The entropy/prefix check on
|
|
202
|
+
// the VALUE is the other obvious fix and this file already records why that direction
|
|
203
|
+
// loses: see the doc-path exemption above, where three shape rules were tried and each
|
|
204
|
+
// one leaked, because a predicate built on what a secret LOOKS like also admits a
|
|
205
|
+
// secret dressed the other way. These literals feed the PUBLIC mirror and session
|
|
206
|
+
// uploads, so a shape hole here is a smuggling channel. That a _MODEL or _BASE_URL var
|
|
207
|
+
// holds a configuration identifier is a fact about the NAME, which cannot be dressed.
|
|
208
|
+
//
|
|
209
|
+
// NARROW BY CONSTRUCTION: this exempts only names matched by the provider PREFIX. A
|
|
210
|
+
// name carrying an actual secret word (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN) matches
|
|
211
|
+
// ENV_SECRET_KEY_RE first and is still collected, whatever it ends with.
|
|
212
|
+
const ENV_CONFIG_NAME_RE = /(?:_MODEL|_BASE_URL)$/i;
|
|
193
213
|
function collectEnvSecrets(env = process.env) {
|
|
194
214
|
const out = [];
|
|
195
215
|
for (const [k, v] of Object.entries(env || {})) {
|
|
196
216
|
if (typeof v !== 'string' || v.length < 8) continue;
|
|
197
217
|
if (ENV_BENIGN_KEY_RE.test(k)) continue;
|
|
198
|
-
|
|
218
|
+
// A secret WORD in the name always wins — it is never exempted below.
|
|
219
|
+
if (ENV_SECRET_KEY_RE.test(k)) { out.push(v); continue; }
|
|
220
|
+
if (ENV_SECRET_PREFIX_RE.test(k) && !ENV_CONFIG_NAME_RE.test(k)) out.push(v);
|
|
199
221
|
}
|
|
200
222
|
return out;
|
|
201
223
|
}
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.786",
|
|
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.786",
|
|
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.786",
|
|
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",
|
package/src/module-api.js
CHANGED
|
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
71
71
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
72
72
|
// the entry to that file. Look for a version's history there, not here.
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
|
-
const CORE_VERSION = '1.19.
|
|
74
|
+
const CORE_VERSION = '1.19.786'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
75
75
|
|
|
76
76
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
77
77
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -327,6 +327,65 @@ test('collectEnvSecrets: benign shell PWD/OLDPWD are skipped, real *_PWD passwor
|
|
|
327
327
|
assert.ok(got.includes(env.MYSQL_PWD), 'MYSQL_PWD (a real password var) must still be collected');
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
+
test('collectEnvSecrets: Claude Code harness config vars are skipped, real anthropic credentials still collected (task 1003512)', () => {
|
|
331
|
+
// Regression: ENV_SECRET_PREFIX_RE matches ^anthropic, so the harness's own
|
|
332
|
+
// ANTHROPIC_DEFAULT_OPUS_MODEL — value = a MODEL ID, not a credential — was collected
|
|
333
|
+
// as a live secret. package-core's fail-closed leak gate then flagged every functional
|
|
334
|
+
// file containing that string verbatim (the grader, llm-pricing and their tests) and
|
|
335
|
+
// refused to build on ANY machine where Claude Code had set its model vars. Hit live
|
|
336
|
+
// packaging 1.19.209; the workaround was `env -u ANTHROPIC_DEFAULT_OPUS_MODEL`.
|
|
337
|
+
const env = {
|
|
338
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-5',
|
|
339
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-5',
|
|
340
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-haiku-4-5-20251001',
|
|
341
|
+
ANTHROPIC_MODEL: 'claude-opus-5-20260101',
|
|
342
|
+
ANTHROPIC_SMALL_FAST_MODEL: 'claude-haiku-4-5-20251001',
|
|
343
|
+
ANTHROPIC_BASE_URL: 'https://api.anthropic.com',
|
|
344
|
+
// ...and the ones that really are credentials, under the SAME provider prefix.
|
|
345
|
+
ANTHROPIC_API_KEY: 'sk-' + 'ant-' + randStr(31, 30, B64URL),
|
|
346
|
+
ANTHROPIC_AUTH_TOKEN: randStr(32, 40, B64URL),
|
|
347
|
+
};
|
|
348
|
+
const got = collectEnvSecrets(env);
|
|
349
|
+
|
|
350
|
+
for (const k of ['ANTHROPIC_DEFAULT_OPUS_MODEL', 'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
351
|
+
'ANTHROPIC_DEFAULT_HAIKU_MODEL', 'ANTHROPIC_MODEL', 'ANTHROPIC_SMALL_FAST_MODEL',
|
|
352
|
+
'ANTHROPIC_BASE_URL']) {
|
|
353
|
+
assert.ok(!got.includes(env[k]), `${k} is a config identifier and must not be collected`);
|
|
354
|
+
}
|
|
355
|
+
// The exemption is on the NAME and must never reach a name carrying a secret word.
|
|
356
|
+
assert.ok(got.includes(env.ANTHROPIC_API_KEY), 'ANTHROPIC_API_KEY must still be collected');
|
|
357
|
+
assert.ok(got.includes(env.ANTHROPIC_AUTH_TOKEN), 'ANTHROPIC_AUTH_TOKEN must still be collected');
|
|
358
|
+
assert.equal(got.length, 2, 'exactly the two real credentials, nothing else');
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test('the *_MODEL exemption cannot be used to smuggle a credential (task 1003512)', () => {
|
|
362
|
+
// A name that carries a secret WORD is collected whatever it ends with — the
|
|
363
|
+
// exemption applies only to names matched by the provider PREFIX alone. Without this,
|
|
364
|
+
// the fix would be a hole: these literals feed the PUBLIC mirror and session uploads.
|
|
365
|
+
const env = {
|
|
366
|
+
ANTHROPIC_SECRET_MODEL: randStr(33, 40, B64URL),
|
|
367
|
+
ANTHROPIC_API_KEY_MODEL: randStr(34, 40, B64URL),
|
|
368
|
+
OPENAI_TOKEN_BASE_URL: randStr(35, 40, B64URL),
|
|
369
|
+
};
|
|
370
|
+
const got = collectEnvSecrets(env);
|
|
371
|
+
for (const k of Object.keys(env)) {
|
|
372
|
+
assert.ok(got.includes(env[k]), `${k} carries a secret word and must still be collected`);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
test('a model id survives a transcript scrub while a real key does not (task 1003512)', () => {
|
|
377
|
+
// The end-to-end shape of the bug: the model id is what package-core found verbatim
|
|
378
|
+
// in modules/grading and failed the build on. RECALL IS UNCHANGED for the credential.
|
|
379
|
+
const env = {
|
|
380
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-5',
|
|
381
|
+
ANTHROPIC_API_KEY: 'sk-' + 'ant-' + randStr(36, 30, B64URL),
|
|
382
|
+
};
|
|
383
|
+
const text = `the grader ran on ${env.ANTHROPIC_DEFAULT_OPUS_MODEL} using ${env.ANTHROPIC_API_KEY}`;
|
|
384
|
+
const out = scrubSecrets(text, collectEnvSecrets(env));
|
|
385
|
+
assert.ok(out.includes('claude-opus-5'), 'a model id is not a secret and must survive');
|
|
386
|
+
assert.ok(!out.includes(env.ANTHROPIC_API_KEY), 'the key must still be scrubbed');
|
|
387
|
+
});
|
|
388
|
+
|
|
330
389
|
test('self-reference `key = key` (SQL SET col = col) survives — zero recall loss', () => {
|
|
331
390
|
// task 1688: the core packager redacts live SQL, so a `_token` COLUMN self-increment
|
|
332
391
|
// must NOT be corrupted — while a real `key = <secret>` assignment is STILL redacted.
|