feat(publish): answer the marketplace scan gate instead of failing on it - #185
Open
A1igator wants to merge 2 commits into
Open
feat(publish): answer the marketplace scan gate instead of failing on it#185A1igator wants to merge 2 commits into
A1igator wants to merge 2 commits into
Conversation
The tenjin backend now runs the publish scan server-side in its shared write path (tenjin#723), so a publisher not running this CLI is gated too. Its refusals reached `publish` and `edit` as opaque post-consent write failures, which is the wrong shape for a decision the operator can act on. Both writing commands map the gate's two codes into the consent flow they already have: `scan_blocked` is a hard exit-3 failure with the redacted findings and no acknowledgement path, and `scan_needs_ack` merges the server's findings with the local scan's, deduped by detector and offset, renders them once, and re-runs the identical content carrying the ack token on an explicit yes. Mode semantics are the local ones: review and auto stop, full-auto acks, and `ackServerWarnings: false` never acks whatever the mode says. Findings travel as data, so a detector this release predates renders faithfully and the server stays authoritative under version skew. Advisory findings on a success response reach the receipt and the human summary as information. Refs #182, tenjin#723. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
A raw NUL byte in the source made git treat scan-gate.ts as binary, so its diff never rendered for review. Same key, written as an escape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
The CLI now answers the server-side ingest scan gate, so a warn-tier refusal becomes a decision the operator can act on instead of an opaque exit-4 write failure.
src/lib/scan-gate.tsparses the two 422 codes and merges server findings with the local scan's, deduped by detector and offset.src/lib/consent.tsmaps them into the exit-3 flowpublishandeditalready share:scan_blockedis terminal with no acknowledgement path,scan_needs_ackrenders once and re-runs the identical content with the ack token on an explicit yes, exactly once. Risk is the wire body:scanAckonly ships on a retry the server itself asked for, so a deployment predating the gate never sees the key on a body its strictObject schema would reject.Mode semantics are the local ones (
src/lib/consent.tsacksServerWarnings): review and auto stop on a server warn, full-auto acks it, andackServerWarnings: falsenever acks whatever the mode says, which is the seam the unattended observer lane needs later.Advisory findings on a success response reach the receipt as
scanand the human summary as informational lines; findings travel as data, so a detector this release predates renders faithfully and the server stays authoritative under version skew.Testing
pnpm lint,pnpm typecheck,pnpm format:check,pnpm build: clean.pnpm test: 2173 passed, 10 skipped, 69 files.src/lib/scan-gate.test.ts(envelope parsing, token-never-on-block, unknown detector and tier, merge/dedupe by offset and by value, malformed-finding drop), 11 command tests inpublish.test.tsand 5 inedit.test.tsagainst a stubbed gate (needs_ack hold, token re-run with identical body, full-auto auto-ack, auto stop, never-ack override, unknown-detector render, blocked in every mode, advisory on success, no-token hold, no loop on a second needs_ack), and one renderer test inoutput.test.tsfor the source marker.Definition of Done
RELEASING.mdgains a server-coupled-releases section: thetenjinrepo'sSCAN_WARN_MODE=enforceflip waits for this release to propagate, which is the whole reason the flag exists.docs/safety-model.mdstates the client/server split: the local scan runs first so a block-tier secret never leaves the machine; the server is authoritative for the marketplace.minor).Notes
A1igator/ingest-scan-gate), built against head5fbed15f. This lands after it merges.openapi.fixture.jsoncontract pin is deliberately untouched:scanAckis not in the deployed contract yet. Regenerate it with the tenjin deploy, not here.skill-drift (mirror is in sync)check does not fire here (noskills/change). Where it does run on a fresh branch it is red for a shared cause owned by feat(cli): tenjin pay and tenjin discover, with the bazaarPay toggle #151, and is not chased.Refs #182, tenjin#723.