Skip to content

Feat/multi repo workspace#4

Merged
Animesh-Sri-bugb merged 4 commits into
mainfrom
feat/multi-repo-workspace
Mar 1, 2026
Merged

Feat/multi repo workspace#4
Animesh-Sri-bugb merged 4 commits into
mainfrom
feat/multi-repo-workspace

Conversation

@Animesh-Sri-bugb

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds multi-repo workspace support to GuardLink (v1.4.0). Multiple service repos can be linked into a unified threat model with cross-repo tag resolution, merged dashboards, and weekly risk tracking.

Workspace module (src/workspace/): Types, workspace.yaml parser/serializer, N-repo merge engine with tag registry and cross-repo reference resolution, link-project with auto-init, sibling discovery, and --add/--remove mutations, agent instruction file injection for cross-repo annotation context.

CLI: guardlink report --format json for per-repo report generation. guardlink merge <files...> with --json, --diff-against, -o, --summary-only. guardlink link-project with --workspace, --registry, --add, --remove.

TUI: /workspace, /link, /merge commands with autocomplete.

MCP: guardlink_workspace_info tool returning workspace context for AI agents.

Parser: detectExternalRefs() scans relationship annotations for tags whose dot-prefix matches a sibling repo name from workspace.yaml. Populates ThreatModel.external_refs on every parse.

Types: ExternalRef interface, ThreatModel.external_refs field, ReportMetadata with repo/workspace/commit_sha/schema_version.

CI templates (examples/ci/): Per-repo workflow (validate on PRs, generate + upload report JSON on push to main) and weekly workspace merge workflow (download artifacts from all repos, merge, dashboard, weekly diff, optional GitHub Pages + Slack).

Docs: docs/WORKSPACE.md — setup guide, workspace.yaml spec, cross-repo annotation rules, merge behavior, CI integration.

Type

  • Bug fix
  • New feature
  • Annotation spec change
  • Documentation
  • CI / tooling

Checklist

  • npm run build passes
  • npm test passes
  • guardlink validate . passes (if annotations changed)
  • CHANGELOG.md updated (for user-facing changes)

Spec changes

Adds ExternalRef interface and optional external_refs field to ThreatModel. Adds optional ReportMetadata to ThreatModel with repo, workspace, commit_sha, and schema_version fields. These are additive — existing reports without these fields remain valid.

…s detection

v1.4.0 workspace feature complete across CLI, TUI, and MCP interfaces.

Workspace module (src/workspace/):
- types.ts: WorkspaceConfig, MergedReport, MergeDiffSummary, tag registry types
- metadata.ts: workspace.yaml parser/serializer, report metadata with repo/workspace fields
- merge.ts: N-repo merge with tag registry, cross-repo ref resolution, stale/schema
  warnings, diff computation, markdown summary + dashboard generation
- link.ts: link-project with auto-init, sibling discovery, --add/--remove mutations,
  agent instruction file injection for cross-repo annotation context
- index.ts: public exports

CLI (src/cli/index.ts):
- guardlink report --format json — JSON report output with metadata
- guardlink merge <files...> --json --diff-against -o --workspace --summary-only
- guardlink link-project <repos...> --workspace --registry
- guardlink link-project --add <repo> --from <existing>
- guardlink link-project --remove <name> --from <existing>

TUI (src/tui/):
- /workspace — show config, sibling repos, registries
- /link — fresh link + --add/--remove mutations
- /merge — merge with --json, --diff-against, -o dashboard
- Autocomplete registration for all workspace commands

MCP (src/mcp/server.ts):
- guardlink_workspace_info tool — workspace name, this_repo, tag prefixes,
  sibling list, cross-repo annotation rules for agents

Parser (src/parser/parse-project.ts):
- detectExternalRefs() — scans relationship annotations for tags with dot-prefix
  matching sibling repo names from workspace.yaml
- Wired into parseProject: model.external_refs populated on every parse
- Fixed optional asset.id type guard

Types (src/types/index.ts):
- ExternalRef interface (tag, context_verb, location, inferred_repo)
- ThreatModel.external_refs field
- ReportMetadata with repo, workspace, commit_sha, schema_version
examples/ci/per-repo-report.yml:
  - Validates annotations on PRs (diff + SARIF + PR comment)
  - Generates report JSON on push to main
  - Uploads as artifact for workspace merge consumption

examples/ci/workspace-merge.yml:
  - Weekly cron (Monday 9am UTC) + manual dispatch
  - Downloads report artifacts from all workspace repos via gh CLI
  - Runs guardlink merge with --diff-against previous week
  - Commits baseline for week-over-week tracking
  - Optional: GitHub Pages deployment, Slack webhook summary

examples/ci/README.md:
  - Setup guide, architecture diagram, configuration reference

Also updated examples/github-action.yml with pointer to workspace templates.
- docs/WORKSPACE.md: multi-repo setup guide covering workspace.yaml spec,
  link-project commands, cross-repo annotation rules, merge behavior,
  CI integration, and weekly workflow
- CHANGELOG.md: v1.4.0 release notes (workspace, merge, link, CI templates,
  external refs, TUI/MCP tools, report --format json)
- package.json: 1.3.0 → 1.4.0
- src/mcp/server.ts: MCP server version 1.3.0 → 1.4.0
README.md:
- Add guardlink_workspace_info to MCP tools table
- Add link-project, merge, report --format json to command table
- Add Multi-Repo CI paragraph under CI section with link to CI guide
- Add Multi-Repo Workspaces section with working example and links

examples/ci/README.md:
- Rewrite as step-by-step setup guide (Steps 1-5)
- Add prerequisite check, exact GitHub navigation paths
- Add What the Merge Output Looks Like with weekly diff example
- Add Troubleshooting section for common failure modes
@Animesh-Sri-bugb Animesh-Sri-bugb merged commit c98af6a into main Mar 1, 2026
3 checks passed
@Animesh-Sri-bugb Animesh-Sri-bugb deleted the feat/multi-repo-workspace branch April 24, 2026 22:16
Animesh-Sri-bugb added a commit that referenced this pull request May 12, 2026
A @flows annotation may now contain more than two participants
connected by ->. The parser expands the chain into N-1 pairwise flows
sharing the same mechanism, description, and source location:

  // @flows User -> #api -> #db via HTTPS -- 'auth path'

becomes

  { source: 'User',  target: '#api', mechanism: 'HTTPS', description: 'auth path' }
  { source: '#api',  target: '#db',  mechanism: 'HTTPS', description: 'auth path' }

Previously, more than one -> caused 'Malformed @flows annotation: could
not parse arguments' because the regex required exactly two ASSET_REF
captures separated by a single arrow. Users had to manually decompose
multi-hop flows into N-1 separate annotation lines.

Implementation:
- src/parser/parse-line.ts: PATTERNS.flows now captures the full chain
  as a single group (ASSET_REF (-> ASSET_REF)+) and the parser splits
  it on /\\s+->\\s+/ to recover the participants array.
- ParseLineResult gains an optional extraAnnotations: Annotation[]
  field for parser branches that emit multiple annotations from one
  line. New okMulti() helper wraps an array into the result shape.
- src/parser/parse-file.ts: call site pushes extraAnnotations and
  updates lastAnnotation to the final hop so '--' continuations on the
  next line attach to the last emitted flow (matches existing semantics).

All downstream consumers (dashboard DFD, sequence diagram generator,
MCP guardlink_lookup flows queries, SARIF export) still see the
pairwise flow shape they always saw — multi-hop is purely a
parser-side expansion. Single-hop A -> B continues to emit exactly
one flow with identical fields to before.

Adds 8 tests in tests/parser.test.ts covering two/three/four-hop
chains, mechanism propagation, description propagation, mixed #id
refs, source-location preservation across hops, and a regression
guard confirming single-hop output is unchanged.

Known limitation (not addressed here): the ASSET_REF pattern still
only accepts #id or Dotted.Path, so URL-style refs like
/rest/user/login or whitespace-containing refs like 'SQLite db' will
still fail with 'Malformed @flows annotation' even after this fix.
Users should declare such targets as @asset App.Routes.Login (#login)
in .guardlink/definitions.ts and reference them as #login. Extending
ASSET_REF to support quoted or URL-shaped refs is a separate concern.

Fixes punch-list bug #4.
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.

1 participant