Merge remote-tracking branch 'origin/main' into capy/opus-55-is-the

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
#	VERSION
#	agents-digest/gstack-AGENTS.md
#	package.json
This commit is contained in:
garrytan committed 2026-10-19 00:28:45 +00:00
commit f0722bc1fe
5 files changed
+21 -3

No files matched your search

+14
View File
@@ -26,6 +26,20 @@ The second Opus gate (run 39161502626) went 127/132. Each of the five reds is no
- **…compare pass rates across the switch:** Fable trials carry `harness_version: 5` and Opus trials `6`; they are separate series.
- **…need Fable for one run:** set `GSTACK_EVAL_MODEL_CAPTURE=claude-fable-5-1` (or `EVALS_MODEL`).
## [1.91.141.0] - 2026-10-18
**Daily `/cso` reports now leave out candidates without demonstrated in-scope impact.** The daily rubric already required an attacker-controlled entrypoint, a security-boundary crossing, demonstrated impact, and challenged protective controls. It now says what to omit: candidates whose impact needs code outside the snapshot or a future change, or that expose nothing sensitive. Those stay coverage evidence instead of supported findings. Comprehensive reports are unchanged and keep unresolved candidates as labeled hypotheses. In the third paid runtime qualification, daily precision was 47/53, below the 0.95 bar, and four of its five false-positive classes were findings of this kind. In a preregistered 12-cell pilot, 5 of the 6 false positives disappeared, every seeded issue was kept, and no new false positive appeared. Daily reports also drop low and informational real issues: 4 of the 13 pilot controls were lost this way. Garry accepted that trade-off. Comprehensive mode still reports them.
### Changed
- **`cso/SKILL.md.tmpl`: the daily supported-finding paragraph names what to omit.** The generated `cso/SKILL.md` is 18,097 bytes, under the 18,100 parity cap. This changes no gate, scorer, threshold, sample count, recall definition, baseline or answer key.
## [1.91.140.0] - 2026-10-18
**/cso evaluation cells that run a repair no longer fail on helper dependency-closure names that use the helper's own 32-character finding IDs.** In the third paid runtime qualification, one comprehensive cell failed with REDACTION_FAILED again, on `dependency-closures/<finding id>-after-<plan hash>.json`. 1.91.135.0 taught the producer this name shape with a 64-character finding ID. The helper actually names closures with its 32-character finding IDs, so real names still fell through to the secret redactor, which reads some of them as wallet addresses.
### Fixed
- **The eval producer recognizes dependency-closure names with 32- or 64-character finding IDs.** Any other word in the phase position still goes through the redactor. The test now uses a real-length, redactor-flagged 32-character name and fails on the 1.91.135.0 pattern.
## [1.91.139.0] - 2026-10-18
**The docs-sync fixture's declared Git interface now includes read-only `git describe`, so `ship-docsync-store` no longer goes red when the /document-release child checks for release tags.** PR #3272's gate run 39153452209 failed that case on one command, `git describe --tags --always`, which the observer did not list. A focused paid rerun of `ship-docsync-store` on this tree passed ($3.83); the child ran the same command twice and the observer accepted it.
+1 -1
View File
@@ -135,7 +135,7 @@ This **CSO evidence rubric** governs CSO instead of shared review confidence ins
- **Confidence:** how strongly available evidence supports that precise claim; explain unknowns and counterevidence. Do not turn a number into proof.
- **Evidence:** candidate hypothesis, supported static evidence, or a helper-recorded reproduction. Code tracing can support a finding; it cannot establish that an application booted or a repair passed tests.
Daily reports contain **supported findings**: a concrete attacker-controlled entrypoint, a path across an intended security boundary, demonstrated impact, and a challenge of relevant protective controls. Comprehensive reports retain unresolved candidates separately as **labeled hypotheses**, never mixed into supported totals. Disproved candidates are retained as disposition/coverage evidence, not vulnerabilities.
Daily reports hold only **supported findings**: an attacker-controlled entrypoint, a security-boundary crossing, demonstrated in-scope impact, and challenged protective controls. Omit daily candidates whose impact needs out-of-snapshot code or a future change, or exposes nothing sensitive. Comprehensive reports keep unresolved candidates as separate **labeled hypotheses**; omitted or disproved ones are coverage.
Do not apply blanket exclusions for development dependencies, availability/resource attacks, historical secrets, user-role prompt injection, or gstack-owned skills. Analyze attacker control and impact. UUIDs are not authorization; user-controlled URL paths can cross a sensitive boundary; environment variables may come from untrusted workflows; framework escape hatches can bypass safe defaults. Missing hardening alone needs a concrete failure scenario before becoming a finding.
+1 -1
View File
@@ -127,7 +127,7 @@ This **CSO evidence rubric** governs CSO instead of shared review confidence ins
- **Confidence:** how strongly available evidence supports that precise claim; explain unknowns and counterevidence. Do not turn a number into proof.
- **Evidence:** candidate hypothesis, supported static evidence, or a helper-recorded reproduction. Code tracing can support a finding; it cannot establish that an application booted or a repair passed tests.
Daily reports contain **supported findings**: a concrete attacker-controlled entrypoint, a path across an intended security boundary, demonstrated impact, and a challenge of relevant protective controls. Comprehensive reports retain unresolved candidates separately as **labeled hypotheses**, never mixed into supported totals. Disproved candidates are retained as disposition/coverage evidence, not vulnerabilities.
Daily reports hold only **supported findings**: an attacker-controlled entrypoint, a security-boundary crossing, demonstrated in-scope impact, and challenged protective controls. Omit daily candidates whose impact needs out-of-snapshot code or a future change, or exposes nothing sensitive. Comprehensive reports keep unresolved candidates as separate **labeled hypotheses**; omitted or disproved ones are coverage.
Do not apply blanket exclusions for development dependencies, availability/resource attacks, historical secrets, user-role prompt injection, or gstack-owned skills. Analyze attacker control and impact. UUIDs are not authorization; user-controlled URL paths can cross a sensitive boundary; environment variables may come from untrusted workflows; framework escape hatches can bypass safe defaults. Missing hardening alone needs a concrete failure scenario before becoming a finding.
+1 -1
View File
@@ -180,7 +180,7 @@ function emptyArtifactInventory(): ProducerArtifactInventory {
}
/** A whole path component that is one of the helper's own identifiers: `<epoch ms>-<hex>` run and replay IDs, retired runs, hex artifact IDs with an optional lowercase-word prefix (`gitleaks-<hex>-<hex>.json`), and dependency-closure files (`<finding id>-before|after-<plan hash>.json`). */
const HELPER_ID_COMPONENT = /^(?:\d{13}-[a-f0-9]{16}|\.retired-\d{13}-[a-f0-9]{16}-[a-f0-9]{32}|(?:[a-z]+-)*[a-f0-9]{16,64}(?:-[a-f0-9]{16})*(?:\.[a-z]+)?|[a-f0-9]{64}-(?:before|after)-[a-f0-9]{16}\.json)$/;
const HELPER_ID_COMPONENT = /^(?:\d{13}-[a-f0-9]{16}|\.retired-\d{13}-[a-f0-9]{16}-[a-f0-9]{32}|(?:[a-z]+-)*[a-f0-9]{16,64}(?:-[a-f0-9]{16})*(?:\.[a-z]+)?|(?:[a-f0-9]{32}){1,2}-(?:before|after)-[a-f0-9]{16}\.json)$/;
/**
* Helper artifact paths are `<repoId>/<runId>/...` plus the helper's public-cache/ and legacy-imports/. Components that
+4
View File
@@ -1218,8 +1218,11 @@ describe('CSO matched producer orchestration', () => {
const repo = 'e'.repeat(24);
let closure = '';
while (!closure) { const name = `${randomHex(32)}-before-${randomHex(8)}.json`; if (redact(name) !== name) closure = name; }
let helperFindingClosure = '';
while (!helperFindingClosure) { const name = `${randomHex(16)}-after-${randomHex(8)}.json`; if (redact(name) !== name) helperFindingClosure = name; }
const accepted = [`${repo}/${runId}/report.json`, `${repo}/${runId}/reviews/${walletShaped}.json`, `${repo}/${runId}/scanner-outcomes/gitleaks-${randomHex(8)}-${randomHex(8)}.json`,
`${repo}/${runId}/dependency-closures/${closure}`, `${repo}/${runId}/dependency-closures/${closure.replace('-before-', '-after-')}`,
`${repo}/${runId}/dependency-closures/${helperFindingClosure}`, `${repo}/${runId}/dependency-closures/${helperFindingClosure.replace('-after-', '-before-')}`,
`${repo}/${runId}/snapshot/test/fixtures/cso-canary-token.txt`, 'public-cache/osv/index.json'];
for (const path of accepted) expect(() => assertProducerArtifactPath(path)).not.toThrow();
for (const [path, message] of [
@@ -1228,6 +1231,7 @@ describe('CSO matched producer orchestration', () => {
[`${repo}/${runId}/bad name.json`, 'INVALID_PRODUCER_ARTIFACTS: an artifact path has a component outside'],
] as const) expect(() => assertProducerArtifactPath(path)).toThrow(message);
expect(() => assertProducerArtifactPath(`${repo}/${runId}/dependency-closures/${closure.replace('-before-', '-during-')}`)).toThrow('looks like a secret');
expect(() => assertProducerArtifactPath(`${repo}/${runId}/dependency-closures/${helperFindingClosure.replace('-after-', '-during-')}`)).toThrow('looks like a secret');
const planted = `sk-ant-api03-${randomHex(24)}`;
expect(redact(planted)).not.toBe(planted);
let failure: unknown;