Skip to content

feat(config): ingest maintainer focus manifests for repo-specific guidance - #191

Merged
JSONbored merged 5 commits into
JSONbored:mainfrom
Khaostica:feat/maintainer-focus-manifests
Jun 1, 2026
Merged

feat(config): ingest maintainer focus manifests for repo-specific guidance#191
JSONbored merged 5 commits into
JSONbored:mainfrom
Khaostica:feat/maintainer-focus-manifests

Conversation

@Khaostica

Copy link
Copy Markdown
Contributor

Summary

  • Closes feat(config): ingest maintainer focus manifests for repo-specific guidance #34. Adds a deterministic maintainer focus manifest ingestion path so repo owners can declare wanted/blocked paths, preferred labels, linked-issue policy, test expectations, issue-discovery policy, and maintainer notes (from a repo file or an API-backed record).
  • New src/signals/focus-manifest.ts tolerantly parses/normalizes the manifest. Missing or malformed config degrades to safe deterministic defaults with warnings instead of crashes, and never throws.
  • Feeds the manifest into local branch analysis: maintainer-blocked paths become branch-quality blockers, wanted paths and preferred labels surface as findings, the linked-issue/test/issue-discovery policies emit findings, and a public-safe "Maintainer Focus" section is added to the PR packet.
  • Public/private boundary: maintainer-private notes are kept out of all public next steps, and every public line passes the forbidden-language redaction guard (no reward/wallet/hotkey/payout/ranking/trust-score/path leakage).
  • Accepts focusManifest on the /v1/local/branch-analysis API and the MCP local-branch tool, and exposes manifestGuidance in the OpenAPI response schema.

Supersedes #74 (closed when its head branch was renamed off the claude/* convention). Rebased onto current main with the src/api/routes.ts, src/mcp/server.ts, and src/services/agent-orchestrator.ts conflicts resolved.

Validation

  • npm run typecheck
  • npm run test:coverage

Verified locally: git diff --check, typecheck, and the focus-manifest, focus-manifest-loader, local-branch, and decision-pack suites pass; src/signals/focus-manifest.ts retains its coverage. Full coverage suite runs green in CI.

  • Changelog updated only if this is a release-prep change (not a release — changelog intentionally untouched)

New/updated tests cover the required scenarios: valid config, missing config, malformed config, blocked-path preflight, preferred-path recommendation, and a public-sanitizer regression — including a deterministic, seeded property-style test built on the existing Vitest stack (no external generator dependency) that asserts public next steps never contain forbidden language across a wide range of generated manifests. (Replaces the earlier fast-check-based test per maintainer feedback, and removes the implicit-any callback parameters.)

Safety

  • Backend-only change
  • No secrets, wallet details, user PATs, raw trust scores, or private rankings exposed
  • Public text avoids compensation-seeking or optimization-tactic language
  • OpenAPI/MCP behavior updated where needed
  • Public docs/changelogs updated where needed (n/a — no public docs affected)

@Khaostica
Khaostica requested a review from JSONbored as a code owner June 1, 2026 14:12
@dosubot dosubot Bot added the size:XL label Jun 1, 2026
@Khaostica
Khaostica force-pushed the feat/maintainer-focus-manifests branch 2 times, most recently from 50b6c7d to 165beeb Compare June 1, 2026 14:27

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Khaostica This needs a rebase. Maintainer focus manifests are a good direction, but the branch conflicts with current main in src/api/routes.ts and src/signals/local-branch.ts.

Please rebase and rerun the full gate. After that, the important review points are manifest schema validation, repo/path scoping, local-branch integration, API/MCP/OpenAPI wiring, and keeping manifest guidance out of public reward-style output.

@Khaostica
Khaostica force-pushed the feat/maintainer-focus-manifests branch from 165beeb to d1da672 Compare June 1, 2026 18:14
Khaostica added 3 commits June 1, 2026 14:37
…dance

Add a deterministic focus-manifest parser that normalizes a repo-owned
manifest (repo file or API-backed record) into wanted/blocked paths,
preferred labels, linked-issue policy, test expectations, issue-discovery
policy, and maintainer notes. Missing or malformed config degrades to safe
defaults with warnings instead of throwing.

Feed the manifest into local-branch analysis so guidance can explain why a
path is preferred or discouraged: blocked paths become branch-quality
blockers, wanted paths and preferred labels surface as findings, and a
public-safe "Maintainer Focus" packet section is added. Maintainer-private
notes never reach public next steps, and all public text passes the
forbidden-language redaction guard.

Accept focusManifest on the local branch-analysis API and MCP tool inputs and
expose manifestGuidance in the OpenAPI response schema.

Closes JSONbored#34.
…d agent

Add a repo-owned focus manifest loader (`.gittensory.json` or
`.github/gittensory.json`, plus a persisted "api_record" path via
upsertRepoFocusManifest) on top of the signal_snapshots table; missing,
malformed, or network-erroring sources degrade to a safe empty manifest
with warnings instead of throwing.

Wire the loader through every consumer:

- /v1/local/branch-analysis and the MCP localBranch tool fall back to the
  repo-owned manifest when no caller-supplied focusManifest is present.
- The agent orchestrator's analyzeLocalBranch path does the same so
  base-agent runs reuse maintainer-declared guidance.
- buildAndPersistContributorDecisionPack bulk-loads per-repo manifests
  and attaches a public-safe RepoDecisionManifestSummary plus
  manifest-driven whyThisHelps / nextActions / publicNextActions /
  riskReasons to each RepoDecision.

Privacy boundary: RepoDecisionManifestSummary intentionally excludes
maintainerNotes, and publicNextActions are run through the existing
forbidden-language guard. New regression tests in decision-pack.test.ts
JSON-stringify a manifested RepoDecision and assert "ping @owner" /
"Internal:" never appear, alongside loader tests that stub the public
GitHub fetcher to cover the file-fetch, error, and api-record paths.
Add tests for the previously-uncovered branches flagged by CI: the
preferred linked-issue and encouraged issue-discovery manifest arms in
buildRepoDecisionManifestReasons, the loader's refresh bypass and
missing/unparseable snapshot-timestamp staleness paths, and the
string-list de-duplication branch in the manifest normalizer.
@Khaostica
Khaostica force-pushed the feat/maintainer-focus-manifests branch 2 times, most recently from d1da672 to 37e8872 Compare June 1, 2026 18:38
@Khaostica
Khaostica requested a review from JSONbored June 1, 2026 18:40

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Khaostica This is ready from my side. The branch has been rebased, the prior merge conflicts are gone, and the current checks are green.

A few notes:

  • The focus manifest parser/loader degrades to safe defaults with warnings instead of throwing.
  • API, MCP, OpenAPI, local-branch, agent-orchestrator, and decision-pack consumers are wired together.
  • The tests cover schema normalization, loader paths, branch guidance, and public-safe decision-pack output so maintainer notes do not leak into public guidance.

No requested changes from me.

@dosubot dosubot Bot added the lgtm label Jun 1, 2026
@JSONbored
JSONbored merged commit 0915ef1 into JSONbored:main Jun 1, 2026
3 checks passed
@dosubot

dosubot Bot commented Jun 1, 2026

Copy link
Copy Markdown

Documentation Updates

1 document(s) were updated by changes in this PR:

For Maintainers
View Changes
@@ -107,6 +107,60 @@
 
 The default label is `"gittensor"` with description `"Gittensor contributor context"` [[14]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/github/labels.ts#L46).
 
+### Maintainer Focus Manifest
+
+Maintainers can create a `.gittensory.json` file (or `.github/gittensory.json`) in their repository to declare wanted paths, blocked paths, preferred labels, linked-issue policy, test expectations, issue-discovery policy, and maintainer notes. This focus manifest allows maintainers to signal their preferences to contributors before they open a PR.
+
+#### Supported Fields
+
+- **`wantedPaths`** (string array) — Path patterns for changes the maintainer wants to see. Supports exact paths, directory prefixes (e.g., `src/`), and wildcards (e.g., `docs/**`).
+- **`blockedPaths`** (string array) — Path patterns for areas the maintainer wants contributors to avoid. Matched paths trigger critical severity findings in preflight checks.
+- **`preferredLabels`** (string array) — Labels the maintainer prefers on PRs for triage alignment.
+- **`linkedIssuePolicy`** (string: `"required"`, `"preferred"`, or `"optional"`) — Whether PRs must link to a tracked issue.
+- **`testExpectations`** (string array) — Free-form guidance on what test evidence the maintainer expects (e.g., "Run `npm test` locally before opening a PR").
+- **`issueDiscoveryPolicy`** (string: `"encouraged"`, `"neutral"`, or `"discouraged"`) — Whether the maintainer welcomes new issue-discovery reports or prefers direct fixes.
+- **`maintainerNotes`** (string array) — Private review context for the maintainer; never appears in public PR threads.
+- **`publicNotes`** (string array) — Public guidance for contributors; shown in packet "Next Steps" and decision-pack recommendations after sanitization.
+
+#### Example
+
+```json
+{
+  "wantedPaths": ["src/", "test/"],
+  "blockedPaths": ["config/secrets.yaml", "internal/**"],
+  "preferredLabels": ["bug", "enhancement"],
+  "linkedIssuePolicy": "required",
+  "testExpectations": ["Run `npm test` locally", "Include test coverage for new features"],
+  "issueDiscoveryPolicy": "encouraged",
+  "publicNotes": ["Small, focused PRs are preferred", "Link discussion in issue thread"]
+}
+```
+
+#### Parsing and Defaults
+
+The manifest uses tolerant parsing with safe defaults. Malformed config degrades gracefully with warnings instead of crashing analysis. Missing or invalid fields fall back to deterministic defaults:
+
+- Missing manifest or empty config → `present: false`
+- Invalid JSON → warning logged, empty manifest returned
+- Invalid field type → field ignored, warning logged
+- Unrecognized policy value → falls back to safe default
+
+All public notes are sanitized to remove forbidden terms (wallet, hotkey, reward, payout, etc.) before appearing in packets or decision-pack guidance.
+
+#### How It Works
+
+When a contributor prepares a PR packet or runs a local branch analysis, Gittensory:
+
+1. Loads the manifest from the repo file (`.gittensory.json` or `.github/gittensory.json`) or a cached snapshot.
+2. Matches the contributor's changed paths against `wantedPaths` and `blockedPaths` patterns.
+3. Checks labels against `preferredLabels`.
+4. Evaluates linked issues, test evidence, and validation results against manifest policies.
+5. Generates findings with severity levels (info, warning, critical) and actionable guidance.
+6. Adds a "Maintainer Focus" section to the PR packet (when the manifest is present) with public-safe next steps.
+7. Merges manifest-driven recommendations into the decision pack's per-repo guidance.
+
+Blocked paths trigger critical severity findings that surface as branch-quality blockers, preventing contributors from opening PRs in maintainer-off-limits areas without explicit confirmation.
+
 ## PR Intelligence
 
 Gittensory surfaces structured, public-safe contribution context directly on GitHub PR threads for confirmed Gittensor miners. This intelligence is deterministic, metadata-only, and deliberately low-noise: maintainers receive one sticky comment with a configured label by default, with private reviewability scoring available separately via the API and control panel.
@@ -588,11 +642,11 @@
 
 ### What Is a PR Packet
 
-A PR packet is assembled by the `buildPublicSafePrPacket()` function, which takes local branch metadata—changed files, validation results, linked issues, base freshness status, and GitHub check state—and produces a markdown document with eight structured sections [[77]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L953-L974). The packet includes a title suggestion derived from the branch name or commit message, and all text is sanitized using `isPublicSafeText()` to remove forbidden terms including `reward`, `score`, `wallet`, `hotkey`, `farming`, `payout`, and local file paths [[78]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L1046-L1052).
+A PR packet is assembled by the `buildPublicSafePrPacket()` function, which takes local branch metadata—changed files, validation results, linked issues, base freshness status, and GitHub check state—and produces a markdown document with nine structured sections [[77]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L953-L974). The packet includes a title suggestion derived from the branch name or commit message, and all text is sanitized using `isPublicSafeText()` to remove forbidden terms including `reward`, `score`, `wallet`, `hotkey`, `farming`, `payout`, and local file paths [[78]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L1046-L1052).
 
 Packets are metadata-only: source code never leaves the local environment [[1]](https://app.dosu.dev/7d8810aa-91c6-4074-849b-92fab65de734/documents/09d20768-c6a2-4ac0-9000-4395a9728dc9). Contributors supply git metadata—branch name, changed file paths, line counts, commit messages, linked issue numbers, and local validation command results—but the packet generation process operates on structured metadata, not file contents.
 
-### Eight Sections in a Packet
+### Nine Sections in a Packet
 
 Every packet contains the following sections [[77]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L953-L974):
 
@@ -600,14 +654,15 @@
 2. **Linked Context** — Lists issues the PR closes (e.g., "Closes #42") or explains why no issue is linked.
 3. **Branch Freshness** — Reports base branch freshness status (fresh, stale, possibly_stale, unknown), staleness warnings, and validation evidence ("3 passed commands").
 4. **GitHub Status** — Current PR state from cached GitHub data (approved, needs author, failing checks, pending review, no PR, unknown) with notes about review decisions and mergeable state.
-5. **Overlap/WIP Check** — Collision signals from cached issue and PR metadata, including possible overlap risk level and related items (e.g., "PR #101, issue #42").
-6. **Changed Paths** — Summary of modified files with change statistics (e.g., "src/api.ts (modified, +42/-18)").
-7. **Validation** — Results of local validation commands with pass/fail status, durations, and summaries.
-8. **Next Steps** — Public-safe actionable recommendations, including preflight findings, base freshness advice, and rerun conditions.
+5. **Maintainer Focus** — Guidance parsed from the maintainer focus manifest (if provided), including wanted/blocked path matches, preferred labels, linked-issue policy, test expectations, issue-discovery policy, and maintainer-supplied public notes. Omitted when no focus manifest is present.
+6. **Overlap/WIP Check** — Collision signals from cached issue and PR metadata, including possible overlap risk level and related items (e.g., "PR #101, issue #42").
+7. **Changed Paths** — Summary of modified files with change statistics (e.g., "src/api.ts (modified, +42/-18)").
+8. **Validation** — Results of local validation commands with pass/fail status, durations, and summaries.
+9. **Next Steps** — Public-safe actionable recommendations, including preflight findings, base freshness advice, and rerun conditions.
 
 ### Additional Metadata
 
-Beyond the eight sections, the packet includes metadata fields for maintainers and contributors [[79]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L152-L164):
+Beyond the nine sections, the packet includes metadata fields for maintainers and contributors [[79]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L152-L164):
 
 - **titleSuggestion** — Derived from branch name or commit message.
 - **markdown** — Full rendered packet in markdown format.
@@ -635,7 +690,7 @@
 3. **Role and lane context** — The system determines whether the contributor is a maintainer, collaborator, or outside contributor, and whether the repository lane is active.
 4. **GitHub branch status** — Cached GitHub data is matched to the current branch via head SHA or branch name, reporting approval status, review decisions, and check states [[83]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L567-L598).
 5. **Sanitization** — All packet text is passed through `isPublicSafeText()`, which removes forbidden terms: `reward`, `score`, `wallet`, `hotkey`, `farming`, `payout`, local file paths [[78]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/src/signals/local-branch.ts#L1046-L1052).
-6. **Final assembly** — The eight sections are rendered into markdown, and metadata fields (title, reviewer notes, validation summary, warnings) are populated.
+6. **Final assembly** — The nine sections are rendered into markdown, and metadata fields (title, reviewer notes, validation summary, warnings) are populated.
 
 ### Privacy and Security
 

How did I do? Any feedback?  Join Discord

@JSONbored JSONbored added gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. and removed feature gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jun 10, 2026
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.

feat(config): ingest maintainer focus manifests for repo-specific guidance

2 participants