Skip to content

docs(miner): document claim ledger in README (#2291) - #1

Closed
kiannidev wants to merge 218 commits into
mainfrom
docs/miner-claim-ledger-readme-2291
Closed

docs(miner): document claim ledger in README (#2291)#1
kiannidev wants to merge 218 commits into
mainfrom
docs/miner-claim-ledger-readme-2291

Conversation

@kiannidev

Copy link
Copy Markdown
Owner

Summary

  • Document the foundation claim ledger in the miner README (openClaimLedger, claimIssue, releaseClaim, listActiveClaims) and note it is local bookkeeping only.
  • Add a README contract test so the documented API surface stays in sync.

Closes JSONbored#2291

Test plan

  • test/unit/miner-claim-ledger-readme.test.ts — README API surface
  • npm run typecheck
  • npm run build --workspace @jsonbored/gittensory-miner

Made with Cursor

jaso0n0818 and others added 30 commits July 5, 2026 01:05
…nrich hold audit metadata (JSONbored#3288)

agentHoldAuditDetail's ciState==="failed" branch returned a bare, unexplained
"auto-action held because CI is failing but no close action was planned" for
EVERY red-CI hold, unconditionally -- it never checked protected-author or
close-autonomy the way the gate-blocker-codes branch a few lines below it
already did. That made a protected owner/admin/automation author and a
"close autonomy isn't auto yet" repo indistinguishable from each other, and
from a genuinely unexplained hold, in the single most common real-world
cause of this message on a self-hosted instance.

Extract the shared protected-author/close-autonomy disambiguation into
closeWithheldReason() and apply it to BOTH branches, so a red-CI hold now
reports "close withheld for protected author" or "close withheld because
close autonomy is <level>" exactly like a gate-blocker hold already does.

Also persist the previously-missing structured fields on the agent.action.hold
audit event's metadata (headSha, gateBlockerTitles, ciFailingCheckNames,
closeEligible, closeAutonomy, mergeAutonomy, protectedAuthor flags,
closeOwnerAuthors, precisionBreakerEngaged/directions) so a hold is fully
debuggable from the audit table alone.

Investigated whether contributor + red CI + close=auto genuinely fails to
plan a close (the reported "biggest product issue"): it does not --
planAgentMaintenanceActions' willClose condition already covers this case
correctly (see the existing "blocked contributor PR ... close=auto" regression
test), and this fix's own new tests confirm a hold only ever reaches the
generic fallback when the author is protected AND close autonomy isn't
auto -- i.e. every reachable hold now has a specific, correct explanation.
…SONbored#3296)

Add high-confidence rules for bb_ (Browserbase) and ak-/as- (Modal token
ID/secret) with truncation and hyphen/underscore continuation tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…SONbored#3292)

Extend isCodeFile and advisory isCodePath so front-end framework source
is recognized consistently in slop signals, missing-tests annotations,
and MCP score-preview mirrors — closing the isCodePath gap that blocked
prior partial fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ed#3294)

generateReplayScoringKey never lints or scrubs frozen context, so it can
only ever reject on selection -- reusing ReplayTaskRejected advertised an
unscrubbable_forward_reference branch this function can never produce.
Adds a regression test pinning the documented eligibility asymmetry
against generateReplayTask for the same candidate.
…ps (JSONbored#3297)

Fills real self-hosting documentation gaps found by audit: undocumented
env vars (maintenance/installation backpressure, foreground liveness,
OTEL, Orb collector overrides, per-provider base URLs, Discord/Slack PR
notifications, Sentry server name, PGVECTOR_ENABLED, PORT) and
.gittensory.yml blocks with zero website coverage (gate.checkMode, the
CLA/expectedCiContexts/rebase-window gate fields, the anti-abuse
settings cluster, contentLane, closeOwnerAuthors/blockedPaths, and the
features: 3-state fallback). Adds explicit config precedence and a link
to .gittensory.yml.example on the configuration page, cross-links it
with the tuning page in both directions, and names
SELFHOST_DEPLOYMENT_MODE explicitly for the instance-wide write
switches it actually controls.
…ng (JSONbored#3291)

Covers two previously undocumented self-hosting topics: how to move a
repo between the hosted managed-beta App and a self-host install (what
carries over via .gittensory.yml vs. what must be re-created, since
settings live in separate databases), and how to cleanly decommission
a self-host instance (revoke the GitHub App, choose what happens to
data volumes, the current lack of a brokered-mode revocation endpoint,
and removing ADMIN_GITHUB_LOGINS access).
…et-scan (JSONbored#3302)

Add high-confidence rules for fal_sk_ (fal.ai) and wandb_v1_ (77-char body)
with truncation and hyphen/underscore continuation regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…JSONbored#3301)

Extend isCodeFile and advisory isCodePath to recognize .cc and .hpp so
native C++ changes align with review/rag.ts indexing and receive correct
slop, missing-tests, and check-run annotation treatment.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ONbored#3306)

Add high-confidence rules for xai- (xAI) and dg. (Deepgram) prefixes with
truncation and hyphen/dot/underscore continuation regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ts (JSONbored#3303)

* test(scoring): cover pure upstream-constant parsers in scoring/model.ts

Closes JSONbored#2091.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(test): use literal density constants in scoring-model test

Avoid Record<string, number> type errors from DEFAULT_SCORING_CONSTANTS indexing.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…JSONbored#3308)

Add high-confidence rules for sk_car_/sk_car_admin_ (Cartesia) and
apify_api_ (Apify) with truncation and continuation regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…cy (JSONbored#3289)

* docs(self-host): add disk capacity planning and backup retention policy

The Disk section had real measured numbers from one production
instance but no way to extrapolate to a larger install, and the
backup-scaling doc never explained how many historical backups the
`backup` profile keeps before pruning. Ground both additions in the
actual growth/retention logic: review_audit and webhook_events have
no retention policy and grow unbounded per PR/webhook, audit_events
is capped at 90 days, and backup.sh keeps BACKUP_RETAIN (default 7)
newest copies per target independently, skipping the sqlite prune
entirely after a failed backup so a known-good copy is never lost.

* fix(docs): tighten backup-retention and capacity-planning wording

The SQLite-failure callout only named the integrity_check failure
mode, missing the .backup-command-itself-fails and empty-output-file
cases the script also treats as failed verification. The review_audit
size estimate mixed a per-row byte figure with an aggregate MB
estimate without a clear derivation; points operators at measuring
their own instance instead of trusting a blanket ratio.
…#3309)

Classify CMakeLists.txt, meson.build, BUILD.bazel, and MODULE.bazel as
build config in path-matchers so native-build-only diffs are not
miscounted as substantive source effort in slop signals.

Co-authored-by: Cursor <cursoragent@cursor.com>
…bored#3317)

Add high-confidence secret-scan rules for Baseten sky_{prefix}.{secret}
federated keys (9-16 char prefix after sky_) and Laminar lmnr_ project
tokens, with boundary, truncation, and continuation negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add high-confidence secret-scan rules for Exa exa_ search keys and Mem0
platform (m0-) and self-hosted (m0sk_) tokens, with truncation and
identifier-continuation negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ilscale TLS profiles (JSONbored#3295)

* docs(self-hosting): correct Grafana exposure claim, document Caddy/Tailscale TLS profiles

security.tsx claimed Grafana's port was private by default alongside Prometheus/Qdrant/Ollama,
but its compose entry publishes 3000:3000 on every interface, unlike Qdrant's confirmed
127.0.0.1-only binding -- correct the claim and note the mitigation. The caddy and tailscale
compose profiles each had exactly one line of documentation anywhere; add a full TLS termination
walkthrough (Caddyfile contents, DNS prerequisites, removing the app's own port mapping,
bring-your-own reverse proxy, Tailscale's network_mode: host and tailnet reachability) and
cross-link it from github-app.tsx's PUBLIC_API_ORIGIN/relay-mode/webhook-check sections and from
quickstart's profile table. Also name and explain docker-proxy, the read-only Docker-socket proxy
that isolates Promtail's service discovery from the raw socket.

* fix(docs): correct Tailscale port-mapping and Caddy TLS-fallback claims

Unlike Caddy, Tailscale's sidecar (network_mode: host) doesn't replace
the app's listener -- it adds a new interface the existing 0.0.0.0
port-publish becomes reachable through. Telling operators to remove
the ports mapping, as for Caddy, makes the app unreachable everywhere,
tailnet included. Also corrects the Caddy TLS section: the shipped
Caddyfile has no fallback directive, so ACME failure for a real domain
does not silently substitute a self-signed cert -- only recognized
non-public hostnames like localhost get that automatically.

* fix(docs): scope the Caddy port-removal rule and stop implying Tailscale satisfies GitHub webhook delivery

The earlier Caddy port-removal callout still named Tailscale as an
alternative, directly contradicting the Tailscale section's own
correction that keeping the mapping is required there. Also corrects
docs.self-hosting-github-app.tsx: PUBLIC_API_ORIGIN and the wizard's
webhook checks previously implied a Tailscale tailnet address could
satisfy GitHub's webhook delivery requirement, which it cannot --
GitHub's servers can't reach a private tailnet address. A Tailscale-
only instance needs brokered pull mode instead.

* fix(docs): remove remaining no-public-port claims about Tailscale

The FeatureRow summary, the section heading, its intro paragraph, the
Grafana-exposure note, and the quickstart page's profile pointer all
still claimed Tailscale removes public reachability on its own -- an
exhaustive grep found and corrected every instance, matching the
detailed explanation already added: the default port mapping keeps
the app reachable on every host interface until you additionally
firewall the host or use tailscale serve.
…ored#3320)

Add high-confidence secret-scan rules for Braintrust bt-st- service tokens
and ScrapeGraphAI sgai- UUID-shaped keys, with truncation and
identifier-continuation negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…Nbored#3321)

Add high-confidence secret-scan rules for Langfuse pk-lf- public keys and
Hyperbolic hb_ API tokens, with truncation and identifier-continuation
negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ored#3290)

* feat(agent): add Linear backend for project/milestone matching (JSONbored#3186)

Lets a repo opt into Linear (via an encrypted per-repo API key) as the
project/milestone-matching backend instead of GitHub Milestones/Projects
v2. Prefers a confirmed native GitHub-link match (Linear's own
attachmentsForURL) over fuzzy title/body matching, and degrades to no
suggestion on any Linear API error or missing key.

* test(agent): cover the linear branch of the backend selector (JSONbored#3186)

Closes the codecov/patch gap flagged on PR JSONbored#3290: the "linear" arm of
parseProjectMilestoneMatchBackend (repositories.ts) and the non-null
arm of the settings.autoProjectMilestoneMatchBackend yml overlay
(focus-manifest.ts) had no test exercising them.

* test(agent): use an explicit placeholder-shaped test secret literal (JSONbored#3186)

The prior fixture ("unit-test-encryption-secret-at-least-32-bytes-long")
was already established convention (verbatim in ai-key-byok.test.ts on
main), but the gate's deterministic generic_secret_assignment hard
blocker has no path-based exemption and only skips values matching its
own placeholder-keyword heuristic. Renaming to include "example" clears
the pattern without changing any test behavior.

* fix(agent): drop dead DB-side timestamp defaults on repository_linear_keys (JSONbored#3186)

Every write to this table goes through Drizzle's $defaultFn, which
always supplies the ISO timestamp explicitly, so the DEFAULT
CURRENT_TIMESTAMP fallback was unreachable in practice. Removing it
resolves the gate's repeated flag on this table without changing any
behavior -- test/unit/linear-key.test.ts:90-98 (an insert that omits
both columns) still passes unchanged.
…bored#3298)

* feat(engine): honor candidatePaths in metadata lane-fit scoring

When discovery metadata includes touched paths, rank metadata candidates
with the same path+label goal model used in analyze instead of labels alone.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(engine): cover computeMetadataLaneFit branches for codecov patch

Exercise non-string and blank candidatePaths through vitest so changed
engine lines meet the 99% patch gate.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…#3325)

Add high-confidence secret-scan rules for Gladia gla_ keys and WorkOS
legacy wos_api_key_ tokens, with truncation and identifier-continuation
negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
JSONbored#3327)

Add high-confidence secret-scan rules for MiniMax sk-cp- subscription
keys and sk-api- pay-per-token keys, with truncation and identifier-
continuation negative tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…#3328)

* feat(engine): add pickTopRankedOpportunities ranker helper

Expose a pure top-N wrapper over rankOpportunities so miners and tools
can cap discovery output without reimplementing ordering or tie-breaks.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(test): restore OpportunityRankInput import for typecheck

The pickTopRankedOpportunities change dropped the type import while
OpportunityRankInput is still used by the ranker test helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: retrigger CI after typecheck fix

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…d#3329)

categorizeFile (analysis-context.ts) recognized only .md/.mdx/.rst/.txt as
docs, so the long-form spellings .markdown, .adoc, and .asciidoc fell through
to the source category — a NOTES.markdown or guide.adoc change was treated as
source rather than documentation.

Add the three spellings to the docs extension list. This matches the canonical
DOCS_EXTENSIONS set in src/signals/path-matchers.ts and rag.ts's DOC_EXT_RE,
which already treat them as docs. Matching is case-insensitive via the existing
lowercased-extension path (README.ADOC classifies as docs).
Rank metadata discovery candidates and return the top N entries using
rankMetadataOpportunities ordering. Lives in metadata-top-pick.ts so
vitest patch coverage instruments every branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
)

Filter ranked discovery candidates by a minimum score threshold with
finite-only input validation and stable rankOpportunities ordering.

Co-authored-by: Cursor <cursoragent@cursor.com>
dhgoal and others added 28 commits July 5, 2026 12:49
…ration test (JSONbored#3602)

Adds a realistic fixture corpus of AI-PR-ban / near-miss docs, a fixture-driven
resolveAiPolicyVerdict test over them, and a fan-out integration test proving a
banned repo is hard-skipped as a pre-filter (excluded before any per-issue
GitHub call, costing exactly one policy fetch). Test-only.

Closes JSONbored#2306
…ed#3621)

Closes JSONbored#2330

Document status/doctor walkthrough, fleet docker pattern, and invariants.

Co-authored-by: Cursor <cursoragent@cursor.com>
…SONbored#2054) (JSONbored#3606)

* docs(config): add minimal .gittensory.minimal.yml starter template

Provide the smallest safe manifest starter with observe-only autonomy and gate off, plus self-host doc links for JSONbored#2054.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(config): drop README link to avoid scope creep

Keep the minimal template limited to the root manifest files.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(config): add minimal .gittensory.minimal.yml starter template

Provide the smallest safe manifest starter with observe-only autonomy and gate off, plus parse test and self-host doc links for JSONbored#2054.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…d#3619)

Add a local, no-network REES analyzer that flags an exported symbol a PR
removes or renames in a package public entrypoint (index/mod/main/public-api)
- a semver-major break for downstream consumers shipped without a major
version bump. Purely diff-driven: for each changed entrypoint file it diffs
the exported names on removed lines against those on added lines and reports a
name that leaves the public surface, so a same-name signature/value edit is
never flagged. Deterministic, conservative, and fail-safe, bounded by
entrypoint and finding caps. Wires the descriptor, BriefFindings type, render
section, canonical name registry, and regenerated analyzer metadata; adds unit
tests covering entrypoint detection, export-name extraction, removal/rename/
edit diffing, the caps, abort, and render.

Closes JSONbored#1510

Co-authored-by: e11734937-beep <e11734937-beep@users.noreply.github.com>
…review (JSONbored#3633)

Adds a --profile visual-review docker-compose service (ghcr.io/browserless/chromium,
internal-network-only, resource-bounded) so self-host operators can enable
automated before/after PR screenshot capture without standing up their own
browser-rendering sidecar. The code-level support (BROWSER_WS_ENDPOINT ->
env.BROWSER injection, the puppeteer-core self-host stub) already existed;
nothing was actually deployed anywhere until now.

Documents BROWSERLESS_TOKEN/BROWSER_WS_ENDPOINT/etc. in .env.example, and
extends scripts/smoke-selfhost.sh with an opt-in visual-review mode that boots
a real browserless container and asserts /gittensory/shot returns an actual
rendered PNG end to end -- verified locally (20526-byte real render of
https://example.com through the full self-host chain).

Entirely additive: unset/default is byte-identical to today (no container, no
screenshots, no error), and docker compose config validates cleanly both with
and without the profile active.
…red#1958) (JSONbored#3634)

Adds a category field (security/correctness/performance/
maintainability/tests/style) to each inline finding: the model
self-categorizes when asked, and a deterministic path/keyword
classifier (classifyFindingCategory) supplies a safe default for
whatever it omits, so a caller with the feature on never sees a
partial tag.

Surfaced in the inline-comment label and a new "Finding categories"
collapsible in the unified comment. Gated by review.finding_categories
in .gittensory.yml (default off, layered on review.inline_comments
like review.suggestions) -- no new global env var, no DB/OpenAPI
surface.
…SONbored#3622)

Bootstrap local SQLite state with gittensory-miner init, extend doctor with sqlite and Docker checks, and document the zero-infra quickstart.

Co-authored-by: Cursor <cursoragent@cursor.com>
…Nbored#3636)

A narrower webhook event's embedded pull_request sub-object can omit
body entirely (undefined) rather than reporting it as explicitly
empty (null/""). Re-deriving linked issues from an absent body was
silently wiping an already-correctly-claimed linked issue -- and
resetting its claim timestamp -- on any such upsert, which could
make the gate report "no linked issue" on a PR that clearly cited
one in a prior, fuller sync.

Falls back to the existing stored value only when body is genuinely
absent; an explicit empty body still clears the claim as before.
…SONbored#3637)

Add a local, deterministic deprecatedDep REES analyzer that flags a direct
dependency a PR newly adds or upgrades when it is an officially deprecated or
unmaintained package with a maintained successor. Reuses the shared manifest
parser and matches added/upgraded names against a bundled curated list per
ecosystem (npm + PyPI); no network, no token. Conservative and fail-safe:
only exact list matches are reported, bounded by manifest/patch/finding caps.

Closes JSONbored#1511

Co-authored-by: e11734937-beep <e11734937-beep@users.noreply.github.com>
…d#3355) (JSONbored#3638)

Document that miner_claims does not adjudicate duplicate winners and add regression tests for the active-only filter (JSONbored#3354).

Co-authored-by: Cursor <cursoragent@cursor.com>
…a drift check (JSONbored#3635)

.gittensory.yml.example is meant to be THE exhaustive reference for every
supported gate/settings/review/features/contentLane/repoDocGeneration field,
but had quietly drifted: gate.aiReview.combine/onMerge/reviewers, ~10
settings fields (contributorBlacklist, linkedIssueHardRules,
unlinkedIssueGuardrail, autoProjectMilestoneMatch(Backend), the 4 disposition
label-name overrides, blacklistLabel, pendingClosureLabel), 12 review.*
fields (footer/note/fields/enrichment/profile/security_focus/
inline_comments/suggestions/changed_files_summary/path_instructions/
instructions/pre_merge_checks/ai_model), and the entire repoDocGeneration
block were never documented at all.

Documents every one of them, then adds an automated exhaustiveness check
(test/unit/focus-manifest.test.ts) so this can't silently drift again: each
config surface gets a `satisfies Record<keyof T, string>` map from field name
to its expected doc token, which is a compile-time error to leave incomplete
when a new field is added to the type -- the same guarantee this repo already
uses for OpenAPI/settings parity and docs-drift checks elsewhere.

Also cross-links the private-config precedence doc (config/examples/README.md)
to the generated SELFHOST_ENV_REFERENCE_ROWS list, since that chain only
covers per-repo review policy, not deployment-level environment variables.
…bored#3351) (JSONbored#3640)

Expose the foundation-phase claim ledger API names with full idempotent claimIssue coverage (JSONbored#3353).

Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(review): keep skill frontmatter first

* fix(review): replace full generated prefix regardless of length change (JSONbored#3639)

replacementStart = Math.max(0, block.startIndex - generatedStartIndex)
only clamped the direction where the fresh prefix is longer than the
stored one. When it's shorter (e.g. a repo rename shortens
repoSkillName, or the description wording changes on a later
refresh), replacementStart landed mid-string inside the old
frontmatter, corrupting the file with a truncated fragment ahead of
the fresh content.

Whenever the renderer declares a prefix at all, the entire file up to
the marker is that prefix by construction (a prefixed doc type is
fully machine-generated, nothing else precedes it) -- so it's always
safe to replace from byte 0 regardless of the old prefix's length. A
prefix-less doc type (marker at byte 0) is unaffected and keeps
preserving real content before the marker exactly as before.
… false positive (JSONbored#3641)

Two independent issues surfaced by JSONbored#3635 merging concurrently with
JSONbored#1958's own review.finding_categories addition:

- main's typecheck is currently broken: JSONbored#3635's new compile-time
  exhaustiveness map (test/unit/focus-manifest.test.ts) predates
  review.finding_categories and is missing that key, which the
  `satisfies Record<...>` check requires. Documents the field in
  .gittensory.yml.example and adds the missing map entry, mirroring
  the review.changed_files_summary entry immediately above it.

- "override of the synthesis merge rule" (added by JSONbored#3635) matches
  gittensory's own INJECTION_SOURCE pattern for "override ... the
  ... rule", so the review pipeline redacted it to
  [external-instruction-redacted] before the AI reviewer ever saw
  it -- correctly, since the redaction can't tell a benign config
  override from a real one without the surrounding context a human
  has. Rewording "rule" to "mode" preserves the exact meaning and
  clears the false positive; confirmed via a direct regex test
  against the full file that no other phrase matches.
Adds a history-class review-enrichment analyzer (JSONbored#1514, part of JSONbored#1499) that
flags a changed file when the PR re-introduces added lines in a region a prior
revert commit removed - a signal the change may be re-treading a path that was
already reverted or hot-fixed out.

For each changed file it reads recent commit history, detects revert commits
(Revert "..." subject or a "This reverts commit <sha>" body), fetches each
revert commit patch, and intersects the reverted old-file line ranges with the
PR added new-file line ranges. Reports only the file, a re-introduced line, a
short revert-SHA prefix, and the reverted PR number when named - never file
contents. Bounded fan-out (5 files / 15 commits / 10 revert lookups / 25
findings); fail-safe on missing token, invalid slug, fetch error, or abort.

Wires the descriptor into the registry, render, types, UI docs, refreshed
metadata, and the analyzer-name lists, with full unit coverage.

Co-authored-by: e11734937-beep <e11734937-beep@users.noreply.github.com>
* feat(review): add per-repo review.visual capture config (JSONbored#3609)

Adds `review.visual` to the .gittensory.yml manifest so a self-hoster
can point the before/after screenshot pipeline at their own repo's
preview setup without any code changes:

- preview.url_template: an explicit "after" preview URL template
  ({number}/{head_sha}/{head_sha_short} placeholders) that always wins
  over GitHub-native preview discovery -- the only option for a
  provider (e.g. Cloudflare Workers Builds' non-production branch
  builds) that never surfaces a GitHub-visible deployment at all.
  Validated at parse time against the same SSRF guard the renderer
  applies at render time (isSafeHttpUrl), so a malformed template
  warns immediately instead of silently degrading to a blank cell.
- routes.paths / routes.max_routes: an explicit route list that
  replaces automatic file-to-route inference for a repo whose routing
  convention isn't gittensory-ui's TanStack file-based one, plus an
  override for the built-in per-PR route cap.

All-absent (default, every repo today) resolves to the existing
GitHub-native discovery chain and automatic route inference, so this
is byte-identical until a maintainer opts in. Also documents the two
review.* fields (finding_categories, visual) that were still missing
from .gittensory.yml.example's field-exhaustiveness map after JSONbored#3635.

Part of JSONbored#3607. Closes JSONbored#3609. Closes JSONbored#3610.

* test(review): cover the reindented buildCapture preview-discovery branches

codecov/patch flagged 91.18% on the prior commit: wrapping the existing
GitHub-native discovery chain in a new `else` block (so the explicit
url_template check could run first) re-indented every line inside it,
which counts as "changed" for patch coverage even though the logic
itself didn't change. Adds the missing branch coverage:
- target.previewUrl already set (skips discovery, no fetch calls)
- getLatestDeploymentStatus throwing (defense-in-depth; the callee
  itself always catches internally and never actually throws today)
- a preview URL found via a commit check run (skips the PR-comment
  fallback)
- every getPreviewBuildState outcome the pending-poll branch reads:
  building, succeeded, and absent (no matching check run at all)
…SONbored#3648)

Assert column layout, NOT NULL constraints, default active status, UNIQUE (repo, issue), and CHECK rejection against the live SQLite table.

Co-authored-by: Cursor <cursoragent@cursor.com>
Closes the foundation claim-ledger scaffold by documenting the local
soft-claim API in the miner package README with a contract test.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kiannidev

Copy link
Copy Markdown
Owner Author

Superseded by JSONbored#3650

@kiannidev kiannidev closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(miner-foundation): local claim ledger scaffold for gittensory-miner