Skip to content

feat(docs): add install site and mcp diagnostics - #1

Merged
JSONbored merged 4 commits into
mainfrom
codex/gittensory-feature-quality-expansion
May 26, 2026
Merged

feat(docs): add install site and mcp diagnostics#1
JSONbored merged 4 commits into
mainfrom
codex/gittensory-feature-quality-expansion

Conversation

@JSONbored

@JSONbored JSONbored commented May 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds the private-beta docs site, install guides, MCP client setup guides, and API/security reference pages.
  • Adds MCP CLI diagnostics and client-config printing so local setup can be checked without mutating user config.
  • Hardens GitHub App installation health by refreshing live app metadata and supporting GitHub's RSA private key PEM format.
  • Keeps the root Worker private and keeps @jsonbored/gittensory-mcp restricted/private for now.

What changed

  • Added VitePress docs under site/ and a gated GitHub Pages workflow.
  • Rewrote README/MCP package docs around private-beta install and later public npm usage.
  • Added docs/package checks to the CI gate and expanded MCP CLI unit coverage.
  • Added live GitHub App installation refresh, RSA private key import support, and health remediation details.
  • Added/updated tests for auth, queue processing, registry parsing, backfill fidelity, GitHub App metadata, MCP CLI behavior, and docs validation.

Why

  • Gittensory needed a clean private-beta closeout path: install docs, local MCP diagnostics, private package safety, and a docs site that can be published without making the repo or npm package public.
  • Installation health needed to read current GitHub App settings instead of relying on stale webhook payload metadata.

Validation

  • git diff --check
  • actionlint .github/workflows/ci.yml .github/workflows/npm-publish.yml .github/workflows/pages.yml
  • gitleaks detect --source . --redact --no-banner
  • npm run test:ci
  • Packed tarball install smoke for @jsonbored/gittensory-mcp
  • Live Worker deploy and smoke: /health, /v1/readiness, /v1/installations, /v1/contributors/jsonbored/decision-pack
  • Live MCP smoke: doctor, whoami, status, analyze-branch, preflight, and stdio tools/list

Notes

  • Live readiness is clean: service ready, public-review ready, core signal fidelity complete, signal fidelity complete, no warnings.
  • GitHub App installation health is healthy with no missing permissions or events.
  • npm package status remains private/restricted; this PR does not publish npm or flip package access public.
  • Pages deploy is gated by GITTENSORY_DOCS_DEPLOY=true and should run from GitHub Actions after merge to main.

JSONbored added 4 commits May 25, 2026 22:28
Add GitHub-backed MCP sessions, rate limiting, queue repair, and npm trusted-publishing readiness.

Keep the Worker private, keep source uploads disabled, and add release gates for the MCP package.
Remove the explicit provenance flag from the MCP publish workflow because npm only generates provenance from eligible public repositories.

Keep the workflow tokenless through trusted publishing and pin the npm CLI used for release publishes.
Bump the MCP package after the unpublished bootstrap version and make future package publishes restricted by default.

Keep the release workflow aligned with the private-beta posture so tags cannot accidentally publish the MCP package publicly.
@JSONbored JSONbored changed the title feat(mcp): harden private beta auth and publishing feat(docs): add install site and mcp diagnostics May 26, 2026
@JSONbored
JSONbored marked this pull request as ready for review May 26, 2026 07:30
@JSONbored
JSONbored merged commit a613357 into main May 26, 2026
0 of 2 checks passed
@JSONbored
JSONbored deleted the codex/gittensory-feature-quality-expansion branch May 29, 2026 08:19
@JSONbored JSONbored added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jun 10, 2026
JSONbored added a commit that referenced this pull request Jun 17, 2026
)

Pre-agent-layer reliability fixes from the 2026-06-17 audit — the gate path must
be solid before it can ever take write actions. Surgical, no signature changes.

- #786 webhook: wrap JOBS.send in try/catch. On enqueue failure, flag the event
  "error" (so the dedup guard lets GitHub redeliver) and return 500 so GitHub
  retries, instead of silently stranding the event as "queued" forever.
- #787 queue: isolate each login in buildContributorDecisionPacks and
  buildContributorEvidence (per-login try/catch) so one failing login can't fail
  the whole batch and poison-pill the queue (which would re-run from login #1).
- #790 public: add a 12s AbortSignal.timeout to fetchPublicContributorProfile's
  two api.github.com calls so a hung response can't stall the 500-login evidence
  loop. (The auth-token rate-ceiling lift is tracked separately on #790.)
- #791 backfill: aggregate contributor stats by canonical lowercase login so one
  user across mixed casings collapses to a single ContributorRepoStatRecord.

New webhook enqueue-failure test; existing tests cover the rest; the trivial
log-and-continue handlers are v8-ignored per the repo idiom. 1892 unit tests
pass; all changed lines covered.

Closes #786
Closes #787
Closes #791
JSONbored added a commit that referenced this pull request Jun 26, 2026
Fourth analyzer behind the REES /v1/enrich contract (top brainstorm pick). For each npm dep
a PR adds/upgrades, fetches the registry packument and flags versions that ship preinstall/
install/postinstall scripts — the #1 npm-malware execution vector, which the shipped CVE scan
misses entirely and the no-checkout reviewer can't see. Public-safe output: package@version +
hook names + publish date (not the script body). Reuses extractDependencyChanges. 3 new
node:test units (19 total) + a live registry check (core-js@3.30.0 → postinstall).
loopover-orb Bot pushed a commit that referenced this pull request Jul 24, 2026
…parse as the overflow check (#8477)

`resolveLinkedIssueHardRule` computed the overflow check from a fresh parse of the
PR's current `body` (`extractLinkedIssueNumbersWithOverflow`) but ran its per-issue
fact-fetch loop against a SEPARATE, caller-supplied `args.linkedIssues` array — a
field synced by an earlier body parse. If a contributor edits their PR description
to add a new closing reference between that sync and this evaluation, the overflow
check (fresh body) and the fact-fetch loop (stale list) disagree about which issues
are "currently linked", and the newly-added issue is silently never evaluated
against the configured hard rules until a later re-sync. That is a real
edit-driven detection-bypass window for a module whose whole purpose is "evaluate
every currently-linked issue's facts against the hard rules."

Fix: parse the body once and drive BOTH the overflow check and the fact-fetch loop
(and the empty early-out) from that single `extractLinkedIssueNumbersWithOverflow`
result, so the two can never disagree. Direction chosen (per the issue's second
option): keep the `linkedIssues` parameter for call-site compatibility but stop
reading it — a surgical change that leaves `src/queue/processors.ts` untouched; the
parameter is documented as retained-but-not-the-source-of-truth.

Add a regression test: a body linking #9 with a stale `linkedIssues: [1]` now
evaluates #9's facts (previously it fetched only #1, 404'd, and reported the wrong
issue). Existing tests that relied on `linkedIssues` driving the fetch were updated
to put the same references in `body` (their intent is unchanged); all still pass.

Closes #8354
JSONbored added a commit that referenced this pull request Jul 26, 2026
…ickiness + flip-count escalation

The AI reviewer is non-deterministic, and the review cache keys purely
on head SHA, so a contributor could force fresh re-rolls (a no-op
recommit invalidating the cache key, or a same-head retry once the
30-minute non-cacheable cooldown lapses) until a lucky clean roll
auto-merged a PR another roll had flagged as blocked. Two independent
defenses:

1. getCachedAiReviewAcrossHeads (src/db/repositories.ts): a fallback
   used only when the exact-head lookup misses. The input fingerprint
   already hashes the actual per-file patch content, not just the head
   SHA, so an identical fingerprint under a different head means the
   reviewed content is genuinely unchanged -- reuse the prior verdict
   instead of spending an independently-random fresh roll on it.

2. A per-PR verdict-flip counter (migration 0183, src/review/
   verdict-flip-guard.ts + verdict-flip-store.ts): every FRESH
   (non-cache-hit) verdict in block mode is compared against the PR's
   last fresh verdict; a flip is a change in whether the verdict had a
   blocking AI defect. Once flips clear a threshold, the gate holds for
   a human instead of trusting the newest roll, regardless of what it
   says.

Fixed a pre-existing test (#ops-review-burst) whose fixture returned
identical patch content across two different head SHAs -- exactly the
no-op-recommit case fix #1 is designed to reuse, which made its own
aiCalls assertion test the wrong thing; it now varies real content
between heads and stays a valid regression for the ORIGINAL concern
(a genuinely new commit is never suppressed).
JSONbored added a commit that referenced this pull request Jul 26, 2026
…ickiness + flip-count escalation (#9094)

* fix(review): stop AI-review verdict-shopping — content-fingerprint stickiness + flip-count escalation

The AI reviewer is non-deterministic, and the review cache keys purely
on head SHA, so a contributor could force fresh re-rolls (a no-op
recommit invalidating the cache key, or a same-head retry once the
30-minute non-cacheable cooldown lapses) until a lucky clean roll
auto-merged a PR another roll had flagged as blocked. Two independent
defenses:

1. getCachedAiReviewAcrossHeads (src/db/repositories.ts): a fallback
   used only when the exact-head lookup misses. The input fingerprint
   already hashes the actual per-file patch content, not just the head
   SHA, so an identical fingerprint under a different head means the
   reviewed content is genuinely unchanged -- reuse the prior verdict
   instead of spending an independently-random fresh roll on it.

2. A per-PR verdict-flip counter (migration 0183, src/review/
   verdict-flip-guard.ts + verdict-flip-store.ts): every FRESH
   (non-cache-hit) verdict in block mode is compared against the PR's
   last fresh verdict; a flip is a change in whether the verdict had a
   blocking AI defect. Once flips clear a threshold, the gate holds for
   a human instead of trusting the newest roll, regardless of what it
   says.

Fixed a pre-existing test (#ops-review-burst) whose fixture returned
identical patch content across two different head SHAs -- exactly the
no-op-recommit case fix #1 is designed to reuse, which made its own
aiCalls assertion test the wrong thing; it now varies real content
between heads and stays a valid regression for the ORIGINAL concern
(a genuinely new commit is never suppressed).

* fix(selfhost): register the verdict-flip-escalation metric and fix a stale migration-number comment

loopover_ai_review_verdict_flip_escalated_total was emitted (processors.ts) with
no DEFAULT_METRIC_META entry, failing the completeness drift guard.

Also corrects verdict-flip-store.ts's header comment, which still said
"migration 0182" -- the ai_review_verdict_flips migration was bumped to 0183
after this branch rebased past #9090's 0181->0182 renumbering, but the comment
was never updated.
JSONbored added a commit that referenced this pull request Jul 28, 2026
…-untested reject arms

Brings packages/loopover-engine/src/review/screenshot-table-gate.ts and
src/signals/change-guardrail.ts (and both re-export shims) to 100% statement,
branch and function coverage.

Three branches had no test on any identity:

- evaluateScreenshotTableGate's PRESENCE-mode freshness checkpoint. Matrix mode's
  identical correlation was pinned by #8866's tests, but presence mode runs it
  through a separate return site and never saw a headSha in a test. Presence mode
  is the DEFAULT shape, so the miss meant one table pasted on push #1 could hold
  the gate green for every later push -- the exact regression the checkpoint
  exists to stop. Six tests: first-push checkpoint, stale-on-new-head (asserting
  no checkpoint is re-issued, which would launder the staleness away after one
  extra push), re-affirmation with fresh URLs, custom message on the stale path,
  no-headSha degradation, and same-head replay.

- guardrailPathMatches' empty-path skip, a deliberate divergence from matchesAny's
  fail-safe: the boolean form matches an empty path under an over-complex glob,
  the structured form must not, because its output is rendered verbatim into
  public review text and audit metadata.

- extractTableRows' non-table reject arm, which is what stops ordinary PR prose
  (and a shell pipe inside backticks) from parsing as table rows.

Mirrored across both import identities so a sharded, flag-merged coverage upload
cannot report a branch as uncovered on one copy.
JSONbored added a commit that referenced this pull request Jul 28, 2026
…-untested reject arms

Brings packages/loopover-engine/src/review/screenshot-table-gate.ts and
src/signals/change-guardrail.ts (and both re-export shims) to 100% statement,
branch and function coverage.

Three branches had no test on any identity:

- evaluateScreenshotTableGate's PRESENCE-mode freshness checkpoint. Matrix mode's
  identical correlation was pinned by #8866's tests, but presence mode runs it
  through a separate return site and never saw a headSha in a test. Presence mode
  is the DEFAULT shape, so the miss meant one table pasted on push #1 could hold
  the gate green for every later push -- the exact regression the checkpoint
  exists to stop. Six tests: first-push checkpoint, stale-on-new-head (asserting
  no checkpoint is re-issued, which would launder the staleness away after one
  extra push), re-affirmation with fresh URLs, custom message on the stale path,
  no-headSha degradation, and same-head replay.

- guardrailPathMatches' empty-path skip, a deliberate divergence from matchesAny's
  fail-safe: the boolean form matches an empty path under an over-complex glob,
  the structured form must not, because its output is rendered verbatim into
  public review text and audit metadata.

- extractTableRows' non-table reject arm, which is what stops ordinary PR prose
  (and a shell pipe inside backticks) from parsing as table rows.

Mirrored across both import identities so a sharded, flag-merged coverage upload
cannot report a branch as uncovered on one copy.
JSONbored added a commit that referenced this pull request Jul 28, 2026
…cabulary, and make inert config queryable (#9554, #9555, #9433) (#9556)

* fix(gate,review,ops): add glob exclusions, tier the public-comment vocabulary, and make inert config queryable (#9554, #9555, #9433)

* test: cover the exclusion matcher from both import identities so shard attribution cannot miss it

* test(gate): cover the presence-mode staleness checkpoint and two long-untested reject arms

Brings packages/loopover-engine/src/review/screenshot-table-gate.ts and
src/signals/change-guardrail.ts (and both re-export shims) to 100% statement,
branch and function coverage.

Three branches had no test on any identity:

- evaluateScreenshotTableGate's PRESENCE-mode freshness checkpoint. Matrix mode's
  identical correlation was pinned by #8866's tests, but presence mode runs it
  through a separate return site and never saw a headSha in a test. Presence mode
  is the DEFAULT shape, so the miss meant one table pasted on push #1 could hold
  the gate green for every later push -- the exact regression the checkpoint
  exists to stop. Six tests: first-push checkpoint, stale-on-new-head (asserting
  no checkpoint is re-issued, which would launder the staleness away after one
  extra push), re-affirmation with fresh URLs, custom message on the stale path,
  no-headSha degradation, and same-head replay.

- guardrailPathMatches' empty-path skip, a deliberate divergence from matchesAny's
  fail-safe: the boolean form matches an empty path under an over-complex glob,
  the structured form must not, because its output is rendered verbatim into
  public review text and audit metadata.

- extractTableRows' non-table reject arm, which is what stops ordinary PR prose
  (and a shell pipe inside backticks) from parsing as table rows.

Mirrored across both import identities so a sharded, flag-merged coverage upload
cannot report a branch as uncovered on one copy.

* fix(ci): declare @loopover/contract#build on the three typecheck tasks that transitively need it

validate-code failed on this PR with 'Cannot find module @loopover/contract/tools'
plus five downstream implicit-any errors in src/mcp/server.ts -- none of which this
PR touches.

#9530 added @loopover/contract, and src/mcp/server.ts imports @loopover/contract/tools.
Three turbo typecheck tasks pull that file into their program without any build edge
to the package:

- @loopover/ui#typecheck: apps/loopover-ui/tsconfig.json includes
  $TURBO_ROOT$/worker-configuration.d.ts, which imports './src/index' -- so the ENTIRE
  Worker is in the UI's typecheck program (src/index.ts -> src/api/routes.ts ->
  src/mcp/server.ts -> @loopover/contract/tools). Confirmed with tsc --explainFiles,
  not inferred. apps/loopover-ui has no package.json dependency on contract, so ^build
  never builds it.
- //#typecheck: a root task, where a root package.json dependency creates no build edge.
- @loopover/ui-miner#typecheck: reaches packages/loopover-miner/lib/**, which imports
  the package, and miner-ui has no dependency on it either.

Each already carries an explicit @loopover/engine#build edge for precisely this reason
-- turbo.json's own comment there describes the same scheduling race, observed
intermittently in validate-code, that bit here.

Cache-dependent, which is why it looked like flakiness: turbo caches these tasks, so
the failure only appears on a cache MISS. Other open PRs are green on cache hits.

Verified both directions from a clean contract build state (dist/ and .tsbuildinfo both
removed, --force):
- with the edges: 4 tasks successful, contract built first, typecheck passes
- without them: the identical six errors CI reported
loopover-orb Bot pushed a commit that referenced this pull request Jul 30, 2026
…t the PR ahead of it (#9954)

The wait comment named the immediate blocker and nothing else:

  Queued in the merge train behind #4, which touches overlapping work and was
  opened first.

"Behind #4" and "behind #4 and six others" are very different waits, and a
queue that will not say which one it is reads as a stall rather than a wait --
which is how it was read in practice.

The information was already computed and thrown away: shouldWaitForOlderSiblings
builds the full sorted list of viable overlapping older siblings and returned
only viable[0]. It now returns the whole list, and the comment reports the
position:

  Queued in the merge train at position 4, behind 3 overlapping PRs opened
  before this one (#1, #2, #3). The nearest is #1.

The single-blocker wording is unchanged -- rendering a one-item queue as "1 PR
ahead: #4" is noise.

The queue inherits every eviction rule the blocker choice already had, which
the tests pin: a draft, a conflicted PR, a manual-review hold and a
non-overlapping sibling are all absent from it. A contributor must never be
told they are behind PRs that are not actually in front of them.

Closes #9952
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant