Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"SendMessage"
],
"deny": [
"Bash(gh release delete:*)",
"Bash(npm publish:*)",
"Bash(pnpm publish:*)",
"Bash(yarn publish:*)"
Expand Down
69 changes: 64 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@ pnpm-debug.log
/emitters/dotnet-tool/obj/
/emitters/dotnet-tool/publish/

# JVM build-tool + IDE residue. The conformance fixtures under test/ run a REAL
# Maven/Gradle invocation inside the fixture dir, so the tool writes its own
# caches next to the tracked build file; the VS Code Java/Gradle extensions then
# drop Eclipse project metadata beside them. Unanchored so a new fixture or
# emitter is covered without another entry.
**/.gradle/
**/target/
**/.settings/
.classpath
.factorypath
.project

# <fleet-pack>
# Fleet-pack untrack set — managed by scripts/repo/bootstrap/fleet.mjs.
# REGENERATED from the release-bundle manifest on every hydrate; stale
Expand All @@ -232,6 +244,12 @@ pnpm-debug.log
.claude/commands/fleet/update-pricing.md
.claude/commands/fleet/update-security.md
.claude/hooks/fleet/_dist/fleet-pack.cjs
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-darwin-arm64
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-darwin-x64
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-linux-arm64
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-linux-x64
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-win32-ia32.exe
.claude/hooks/fleet/_dist/launchers/dispatch-launcher-win32-x64.exe
.claude/hooks/fleet/_shared/.clangd
.claude/hooks/fleet/_shared/README.md
.claude/hooks/fleet/_shared/active-edits-ledger.mts
Expand Down Expand Up @@ -348,6 +366,8 @@ pnpm-debug.log
.claude/hooks/fleet/_shared/verdict.mts
.claude/hooks/fleet/_shared/waiting-discipline.mts
.claude/hooks/fleet/_shared/wheelhouse-root.mts
.claude/hooks/fleet/account-snapshot-recorder/README.md
.claude/hooks/fleet/account-snapshot-recorder/index.mts
.claude/hooks/fleet/actionlint-on-workflow-edit/README.md
.claude/hooks/fleet/actionlint-on-workflow-edit/index.mts
.claude/hooks/fleet/actionlint-on-workflow-edit/package.json
Expand Down Expand Up @@ -728,6 +748,12 @@ pnpm-debug.log
.claude/hooks/fleet/minimum-release-age-guard/index.mts
.claude/hooks/fleet/minimum-release-age-guard/package.json
.claude/hooks/fleet/minimum-release-age-guard/tsconfig.json
.claude/hooks/fleet/model-policy-guard/README.md
.claude/hooks/fleet/model-policy-guard/index.mts
.claude/hooks/fleet/model-policy-guard/model-policy.mts
.claude/hooks/fleet/model-policy-guard/settings-layers.mts
.claude/hooks/fleet/model-spawn-policy-guard/README.md
.claude/hooks/fleet/model-spawn-policy-guard/index.mts
.claude/hooks/fleet/module-noun-name-guard/README.md
.claude/hooks/fleet/module-noun-name-guard/index.mts
.claude/hooks/fleet/module-noun-name-guard/package.json
Expand Down Expand Up @@ -1216,6 +1242,7 @@ pnpm-debug.log
.claude/hooks/fleet/reply-prose-nudge/index.mts
.claude/hooks/fleet/reply-prose-nudge/package.json
.claude/hooks/fleet/reply-prose-nudge/tsconfig.json
.claude/hooks/fleet/reply-ref-link-guard/index.mts
.claude/hooks/fleet/repo-map-refresh/index.mts
.claude/hooks/fleet/report-location-guard/README.md
.claude/hooks/fleet/report-location-guard/index.mts
Expand Down Expand Up @@ -1321,6 +1348,8 @@ pnpm-debug.log
.claude/hooks/fleet/soak-pin-needs-annotation-guard/index.mts
.claude/hooks/fleet/soak-pin-needs-annotation-guard/package.json
.claude/hooks/fleet/soak-pin-needs-annotation-guard/tsconfig.json
.claude/hooks/fleet/spend-warning-nudge/README.md
.claude/hooks/fleet/spend-warning-nudge/index.mts
.claude/hooks/fleet/squash-freeze-boundary-guard/index.mts
.claude/hooks/fleet/squash-freeze-boundary-guard/package.json
.claude/hooks/fleet/squash-freeze-boundary-guard/tsconfig.json
Expand Down Expand Up @@ -1568,6 +1597,8 @@ pnpm-debug.log
.claude/skills/fleet/migrating-rule-packs/SKILL.md
.claude/skills/fleet/migrating-rule-packs/lib/run-migration-worktree.mts
.claude/skills/fleet/migrating-rule-packs/lib/run-migration.mts
.claude/skills/fleet/mocking-vendor-screens/SKILL.md
.claude/skills/fleet/mocking-vendor-screens/npm-mockup.mts
.claude/skills/fleet/opening-pr/SKILL.md
.claude/skills/fleet/optimizing-compiler-performance/SKILL.md
.claude/skills/fleet/optimizing-cpp-performance/SKILL.md
Expand Down Expand Up @@ -1606,6 +1637,9 @@ pnpm-debug.log
.claude/skills/fleet/prose/references/phrases.md
.claude/skills/fleet/prose/references/structures.md
.claude/skills/fleet/pushing/SKILL.md
.claude/skills/fleet/recording-ui-walkthroughs/SKILL.md
.claude/skills/fleet/recording-ui-walkthroughs/profiles/npm-create-token.json
.claude/skills/fleet/recording-ui-walkthroughs/record-walkthrough.mts
.claude/skills/fleet/refreshing-history/SKILL.md
.claude/skills/fleet/refreshing-history/run.mts
.claude/skills/fleet/releasing-a-package/SKILL.md
Expand Down Expand Up @@ -1946,6 +1980,7 @@ pnpm-debug.log
.config/fleet/playwright/agent-banner-shield.svg
.config/fleet/playwright/agent-banner.js
.config/fleet/playwright/challenge-screen.js
.config/fleet/playwright/operator-note.js
.config/fleet/pnpm-workspace.fleet.yaml
.config/fleet/rolldown/hook-bundle-excluded.config.mts
.config/fleet/rolldown/hook-bundle-snapshot.config.mts
Expand Down Expand Up @@ -2102,6 +2137,7 @@ docs/agents.md/fleet/release-pins-are-canonical.md
docs/agents.md/fleet/release-tag-escape-hatch.md
docs/agents.md/fleet/release-vs-cascade.md
docs/agents.md/fleet/repo-map.md
docs/agents.md/fleet/reporting-in-ste100.md
docs/agents.md/fleet/researching-recency.md
docs/agents.md/fleet/runtime-feature-floors.md
docs/agents.md/fleet/runtime-state-and-caches.md
Expand Down Expand Up @@ -2158,6 +2194,8 @@ scripts/fleet/_shared/check-steps-hooks.mts
scripts/fleet/_shared/check-steps-paths.mts
scripts/fleet/_shared/check-steps-release.mts
scripts/fleet/_shared/check-steps.mts
scripts/fleet/_shared/claude-usage-breakdowns.mts
scripts/fleet/_shared/claude-usage.mts
scripts/fleet/_shared/dispatch-scan.mts
scripts/fleet/_shared/fixer-lock.mts
scripts/fleet/_shared/fixture-names.mts
Expand All @@ -2170,9 +2208,11 @@ scripts/fleet/_shared/git-porcelain.mts
scripts/fleet/_shared/github-raw-url.mts
scripts/fleet/_shared/github-tracked-surface.mts
scripts/fleet/_shared/gitmodules.mts
scripts/fleet/_shared/go-workspaces.mts
scripts/fleet/_shared/hook-wiring.mts
scripts/fleet/_shared/human-gate.mts
scripts/fleet/_shared/is-main-module.mts
scripts/fleet/_shared/launcher-variants.mts
scripts/fleet/_shared/lifecycle-scripts.mts
scripts/fleet/_shared/lint-runners.mts
scripts/fleet/_shared/managed-ruleset-identity.mts
Expand All @@ -2187,6 +2227,7 @@ scripts/fleet/_shared/pack-structure.mts
scripts/fleet/_shared/pinned-ref.mts
scripts/fleet/_shared/playwright-law.mts
scripts/fleet/_shared/pnpm-lockfile.mts
scripts/fleet/_shared/poll-with-decay.mts
scripts/fleet/_shared/pr-body-law.mts
scripts/fleet/_shared/process-lifecycle.mts
scripts/fleet/_shared/prose-em-dash.mts
Expand All @@ -2205,6 +2246,7 @@ scripts/fleet/_shared/scope-flags.mts
scripts/fleet/_shared/security-posture-law.mts
scripts/fleet/_shared/security-posture-probe.mts
scripts/fleet/_shared/spawn-env-scan.mts
scripts/fleet/_shared/swift-targets.mts
scripts/fleet/_shared/tar-executable.mts
scripts/fleet/_shared/template-payload-scope.mts
scripts/fleet/_shared/terminal-link.mts
Expand Down Expand Up @@ -2232,6 +2274,8 @@ scripts/fleet/analyze-range-consolidation/ecosystems/npm.mts
scripts/fleet/analyze-range-consolidation/override-audit-report.mts
scripts/fleet/analyze-range-consolidation/override-audit.mts
scripts/fleet/analyze-range-consolidation/verdict.mts
scripts/fleet/apple-notarize.mts
scripts/fleet/apple-sign.mts
scripts/fleet/audit-transcript.mts
scripts/fleet/auditing-history/lib/patch-id.mts
scripts/fleet/auditing-history/lib/types.mts
Expand All @@ -2248,10 +2292,6 @@ scripts/fleet/backup-branches/unique-content.mts
scripts/fleet/build-hook-bundle.mts
scripts/fleet/build-hook-snapshot.mts
scripts/fleet/build-infra/lib/external-tools-schema.json
scripts/fleet/build-infra/lib/release-checksums/consumer.mts
scripts/fleet/build-infra/lib/release-checksums/core.mts
scripts/fleet/build-infra/lib/release-checksums/producer.mts
scripts/fleet/build-infra/release-assets.schema.json
scripts/fleet/build-oxlint-bundle.mts
scripts/fleet/build-snapshot-launcher.mts
scripts/fleet/bump.mts
Expand All @@ -2267,6 +2307,7 @@ scripts/fleet/cache/tar-archive.mts
scripts/fleet/cache/twirp.mts
scripts/fleet/cargo-publish.mts
scripts/fleet/check.mts
scripts/fleet/check/account-identity-is-not-committed.mts
scripts/fleet/check/action-pins-are-current.mts
scripts/fleet/check/action-ports-are-lock-stepped.mts
scripts/fleet/check/actions-are-segmented.mts
Expand Down Expand Up @@ -2303,6 +2344,7 @@ scripts/fleet/check/claude-md-citations-resolve.mts
scripts/fleet/check/claude-md-repo-section-is-a-bullet-index.mts
scripts/fleet/check/claude-md-rules-are-enforced.mts
scripts/fleet/check/claude-md-rules-are-informative.mts
scripts/fleet/check/claude-settings-fleet-markers-are-short.mts
scripts/fleet/check/comment-markers-are-honeypot-inert.mts
scripts/fleet/check/commits-are-signed.mts
scripts/fleet/check/commits-have-no-ai-attribution.mts
Expand Down Expand Up @@ -2429,6 +2471,7 @@ scripts/fleet/check/pnpm-run-flags-have-no-bare-dash.mts
scripts/fleet/check/pr-refs-in-docs-are-linked.mts
scripts/fleet/check/precommit-steps-are-bounded.mts
scripts/fleet/check/prettierignore-globs-are-anchored.mts
scripts/fleet/check/priced-models-cover-observed-usage.mts
scripts/fleet/check/pricing-data-is-current.mts
scripts/fleet/check/private-packages-are-unpublishable.mts
scripts/fleet/check/private-paths-are-absent.mts
Expand Down Expand Up @@ -2499,6 +2542,7 @@ scripts/fleet/check/upstream-contracts-are-current.mts
scripts/fleet/check/upstream-gitlinks-are-absent.mts
scripts/fleet/check/upstream-submodules-are-release-tagged.mts
scripts/fleet/check/upstream-submodules-are-shallow-single-branch.mts
scripts/fleet/check/usage-dedup-key-is-sound.mts
scripts/fleet/check/uv-lockfiles-are-current.mts
scripts/fleet/check/version-derivation-jobs-have-tags.mts
scripts/fleet/check/version-is-not-ahead-of-published.mts
Expand Down Expand Up @@ -2551,7 +2595,6 @@ scripts/fleet/cover/runner.mts
scripts/fleet/cover/rust-lane.mts
scripts/fleet/cover/scratch-isolation.mts
scripts/fleet/crate-release-sha.mts
scripts/fleet/create-release.mts
scripts/fleet/cross-cli/fleet-fork-detect.mts
scripts/fleet/cross-cli/pretooluse-hook.mts
scripts/fleet/depot-ci.mts
Expand All @@ -2571,8 +2614,15 @@ scripts/fleet/external-tools/schema.mts
scripts/fleet/external-tools/show.mts
scripts/fleet/external-tools/update.mts
scripts/fleet/fetch-fleet-pack.mts
scripts/fleet/fix-cpp.mts
scripts/fleet/fix-go.mts
scripts/fleet/fix-rust.mts
scripts/fleet/fix-swift.mts
scripts/fleet/fix.mts
scripts/fleet/fmt-cpp.mts
scripts/fleet/fmt-go.mts
scripts/fleet/fmt-rust.mts
scripts/fleet/fmt-swift.mts
scripts/fleet/format.mts
scripts/fleet/fsync-dist.mts
scripts/fleet/gen/agents-skills-mirror.mts
Expand Down Expand Up @@ -2656,12 +2706,15 @@ scripts/fleet/lib/telemetry-scan.mts
scripts/fleet/lib/verify-release-hashes.mts
scripts/fleet/lib/workspace-yaml.mts
scripts/fleet/lint-actions.mts
scripts/fleet/lint-cpp.mts
scripts/fleet/lint-github-settings.mts
scripts/fleet/lint-github-settings/detect.mts
scripts/fleet/lint-github-settings/evaluate.mts
scripts/fleet/lint-github-settings/types.mts
scripts/fleet/lint-go.mts
scripts/fleet/lint-pr-comment.mts
scripts/fleet/lint-rust.mts
scripts/fleet/lint-swift.mts
scripts/fleet/lint.mts
scripts/fleet/lockstep-emit-mirror-globs.mts
scripts/fleet/lockstep-emit-schema.mts
Expand Down Expand Up @@ -2703,6 +2756,10 @@ scripts/fleet/prune-actions-caches.mts
scripts/fleet/prune-workflow-runs.mts
scripts/fleet/publish-pipeline.mts
scripts/fleet/publish-shared.mts
scripts/fleet/registry-infra/apple/developer-id-cert.mts
scripts/fleet/registry-infra/apple/developer-id-page.mts
scripts/fleet/registry-infra/apple/developer-id-plan.mts
scripts/fleet/registry-infra/apple/keychain-csr.mts
scripts/fleet/registry-infra/cargo/approve.mts
scripts/fleet/registry-infra/cargo/bump.mts
scripts/fleet/registry-infra/cargo/placeholder.mts
Expand Down Expand Up @@ -2782,6 +2839,7 @@ scripts/fleet/release-pipeline/staged-commit.mts
scripts/fleet/release-pipeline/stages.mts
scripts/fleet/release-pipeline/state.mts
scripts/fleet/release-pipeline/summary.mts
scripts/fleet/report-claude-usage.mts
scripts/fleet/researching-recency/cli.mts
scripts/fleet/researching-recency/lib/dedupe.mts
scripts/fleet/researching-recency/lib/fetch.mts
Expand Down Expand Up @@ -2871,6 +2929,7 @@ scripts/fleet/socket-wheelhouse-schema/policy.mts
scripts/fleet/socket-wheelhouse-schema/testing.mts
scripts/fleet/socket-wheelhouse-schema/tooling.mts
scripts/fleet/source-pricing-feed.mts
scripts/fleet/spend-statusline.mts
scripts/fleet/strip-ai-tags.mts
scripts/fleet/sync-gh-aw-action-pins.mts
scripts/fleet/sync-oxlint-rules.mts
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@
- 🚨 `src/contract/` is a wire format a second implementation parses with a
`.strict()` schema, so an additive field is a coordinated release, never a
local edit. [`contract`](docs/agents.md/repo/contract.md)
- 🚨 The sidecar's `classifier` serializes as an explicit JSON `null`; the fleet's
`undefined`-over-`null` preference stops at the wire.
- 🚨 The sidecar is keyed by absolute `.socket.facts.json` path: the key IS the
per-subproject reachability scope, and there is NO cross-reactor dedup.
[`contract`](docs/agents.md/repo/contract.md)
- 🚨 The conformance oracle diffs emitted facts against the BUILD's own report, never a golden file. [`ground-truth-oracle`](docs/agents.md/repo/ground-truth-oracle.md)
- 🚨 Only `extra` is tolerated in that diff; `missing`, `version-mismatch`, and a missing edge never are. [`ground-truth-oracle`](docs/agents.md/repo/ground-truth-oracle.md)
Expand Down
83 changes: 38 additions & 45 deletions docs/agents.md/repo/contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ library rather than a socket-cli internal, so treat them as published shapes.

The reachability consumer hand-maintains its own copies:

- `coana-package-manager/packages/shared-types/src/socket-facts-schema.ts` - a
parallel type declaration of the SBOM side.
- `.../java/sidecar-artifact-paths.ts` - a zod schema for the sidecar, with
`.strict()` on the component object.
- a parallel type declaration of the SBOM side, in its shared-types package.
- `sidecar-artifact-paths.ts` in its JVM reachability analyzer - a zod schema for
the sidecar: a record keyed by facts-file path, with `.strict()` on both the
component and the project object.

Two hand-maintained copies of one format drift, and the drift is silent until a
scan produces the wrong answer. What this package exports is a superset the
Expand All @@ -25,20 +25,15 @@ already reimplements.
When a coordinate is missing from the sidecar, the consumer does not skip it and
does not downgrade its vulnerabilities to a precomputed result. It resolves the
coordinate itself, best-effort: local caches first, then
`mvn -Dtransitive=false dependency:get`, then HTTP. The fallback lives in
`coana-package-manager/packages/reachability-analyzers/src/whole-program-code-aware-vulnerability-scanner/java/java-code-aware-vulnerability-scanner.ts:807-826`,
calling the `resolveArtifact` helper at line 710 of the same file.
`mvn -Dtransitive=false dependency:get`, then HTTP. The fallback lives in the
consumer's JVM reachability scanner, in its own artifact-resolution helper.

The history is worth knowing, because the short-lived behavior is the one people
remember. Coana's
[#2292](https://github.com/coana-tech/coana-package-manager/pull/2292)
(`548637bbc`, 2026-06-30) landed the sidecar consumer with a hard short-circuit:
uncovered meant unresolved.
[#2295](https://github.com/coana-tech/coana-package-manager/pull/2295)
(`5d3056a1b`, 2026-07-01) relaxed it the next day, because reachability is not
scoped per project yet, so a scan legitimately carries artifacts from
subprojects outside the sidecar's build root. The pinned 15.9.5 contains the
relaxed behavior.
remember. The consumer first landed the sidecar with a hard short-circuit on
2026-06-30: uncovered meant unresolved. It relaxed that the next day, because
reachability is not scoped per project yet, so a scan legitimately carries
artifacts from subprojects outside the sidecar's build root. The version pinned
today carries the relaxed behavior.

The consequence is the load-bearing part. **The sidecar is an accelerator, not an
authority.** A gap does not fail the scan and does not narrow it - it silently
Expand All @@ -49,41 +44,39 @@ concern worth surfacing, not a benign fallback. Nothing in the wire format
signals the miss; the only evidence is a `resolvedSource` other than `sidecar` /
`sidecar-no-artifact` in the consumer's debug log.

## `classifier` serializes as an explicit JSON null

The fleet prefers `undefined` over `null` everywhere except here. The sidecar's
consumer types `classifier` as `z.string().nullable()`, and an absent key is a
different payload from an explicit `null`. `validateResolvedPathsSidecar`
therefore rejects a component whose `classifier` key is missing, even though
every other absent-optional would be fine.

## An additive field is a coordinated release

The sidecar consumer's component schema is `.strict()`. Under a strict schema an
The sidecar consumer parses each component AND each project with a `.strict()`
schema, inside a record keyed by facts-file path. Under a strict schema an
unrecognized key is not ignored - it fails the parse, and the failure is
whole-payload, not per-field. So adding **any** field to `ResolvedComponent`,
including a `schemaVersion` intended to make future additions safe, breaks every
consumer pinned to a version released before the addition.
whole-payload, not per-field. So adding **any** field to `SidecarComponentEntry`
or `SidecarProjectEntry`, including a `schemaVersion` intended to make future
additions safe, breaks every consumer pinned to a version released before the
addition.

`validateResolvedPathsSidecar` enforces this from the producer side: an unknown
key is a violation here, so a producer cannot emit a payload the consumer will
reject.

### `ecosystem` is the one field added under that rule

`ResolvedComponent.ecosystem` carries the artifact's purl type, because a
groupless NuGet id and a Maven artifactId can produce the same coordinate key
and there is no other way to tell them apart. Adding it follows the rule above
rather than escaping it: **every** reachability scan, single-ecosystem JVM ones
included, fails at the sidecar handoff until the consumer's schema accepts the
key, because the producer stamps the tag on every entry and a `.strict()` parse
rejects the whole payload rather than the one field. Releasing the consumer's
schema change first is the gate on shipping a version of this package that
emits it.

The validator is asymmetric here on purpose: it accepts a payload with no
`ecosystem` key, because that is exactly what a sidecar written before the tag
existed looks like, and it means `maven`. Strict producer, liberal consumer.
reject. `SIDECAR_COMPONENT_FIELDS` and `SIDECAR_PROJECT_FIELDS` are sorted so
each list diffs against the consumer's own `.strict()` object at a glance.

### The facts-file key is the scope

The sidecar is keyed by the absolute path of the `.socket.facts.json` whose own
`projects[]`/`components[]` each bucket describes, and that key is what
per-subproject reachability reads. Two independent reactors that emit the same
purl identity cannot collide, because each is only ever looked up within its own
key. There is no cross-reactor deduplication: the same external dependency
resolved by several reactors is deliberately duplicated across all of their
`components[]`, which is simpler and safer than a shared bucket.

### The purl `type` discriminates the ecosystem

A groupless NuGet id and a Maven artifactId can produce the same coordinate key,
and an entry's purl `type` is what tells them apart - `maven` for
gradle/maven/sbt, `nuget` for dotnet. It is the facts entry's own `type` carried
through verbatim, so there is no narrowing and no re-derivation. An artifact's
packaging and classifier travel in `qualifiers.ext` and
`qualifiers.classifier`, the same places the SBOM puts them.

### Proposed versioning approach - not adopted

Expand Down
Loading