Skip to content

feat: add portable project bundles - #7181

Open
kyleseaman wants to merge 1 commit into
mainfrom
feat/project-bundles
Open

feat: add portable project bundles#7181
kyleseaman wants to merge 1 commit into
mainfrom
feat/project-bundles

Conversation

@kyleseaman

@kyleseaman kyleseaman commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Summary - add portable Project bundles with stable identity and no user identity, loaded from a local folder or a managed Git clone - put Projects under Agent Capabilities, with a focused list/detail/create/add/sync flow that supports multiple repositories, agents, skills, and MCP configuration - let a Project be selected when creating a session and show the Project name in-session while resolving the full multi-repository workspace for the agent - add owner-gated capability review, trust, activation, refresh, and withdrawal with namespaced materialization and Project MCP provenance - keep v1 manifest editing as an ordinary file-and-Git workflow; sync or remove/re-add applies external project.yaml changes - update the Projects RFC and system specifications to match the shipped v1 contract ## Safety and compatibility - keep bundle content inert until explicit owner trust and SEL audit; bind approval to a content digest over repo declarations, context selectors, agent JSON, skill trees, and MCP JSON - show agent names and exact MCP server commands, arguments, and URLs before a separate trust confirmation - withdraw an active materialization on sync when that digest changes, requiring explicit owner re-review instead of silently installing upstream capabilities - do not expose an in-app manifest replacement endpoint until the filesystem destination can be updated with a true atomic compare-and-swap - clone each derived repository source once, then reuse that validated checkout as a disclosed stale cache without reopening it by name for Git writes; removal and re-addition rebuild derived state - audit allowed and denied Project authorization decisions, reject control characters in workspace paths before prompt construction, accept only canonical persisted Project UUIDs, and keep blocking path resolution off the gateway event loop - redact Project attachment failures before dashboard JSON, diagnostic logs, or persisted and broadcast session errors - redact credentials and exfiltration URLs from Project briefs before model context, reject decoded Git control characters, and fail closed on corrupt activation state or registry path loops - preserve configuration-equal MCP entries that the owner reclaims by removing Project provenance - reject malformed persisted Project ids during both restart restore paths and keep Git transport tests independent of host sandbox availability while pinning production fail-closed behavior - reject credentials, embedded grants, sensitive Git paths, network file:// authorities, path escapes, links, hardlink aliases, recursive YAML, and alias-amplified manifests - resolve relative repo paths against the declaring bundle before both the security decision and Git clone - use descriptor-pinned or opened-handle-validated reads for the manifest and bundle-owned executable JSON - preflight fetched Git blob size before buffering a remote Project manifest - drop and audit Project briefs that match prompt-injection screening, neutralize structural markers in benign briefs, and reconcile Project MCP revocation inside the final rendered-config lock - preserve the legacy Task Runner /api/projects contract and keep local credentials/install identity out of the portable manifest ## Screenshots | Projects in Agent Capabilities | Project details | | --- | --- | | Projects list | Project details | | Reviewed capabilities active | Project attached to a session | | --- | --- | | Active Project capabilities | Project session | ## Verification - Project backend suite: 707 passed - focused Projects UI and bundle-gate suite: 180 passed - production portal analyze build and bundle-size gate passed - Python formatting, focused flake8, Linux-parity mypy, subprocess-encoding, docs, TypeScript, ESLint, and clean diff checks passed - offline browser E2E now covers the external Git edit → Project sync → trust → multi-repo session flow; targeted real-gateway Chromium run passed (2/2); exact-head CI is rerunning ## Notes - no linked issue: this feature was developed directly from the Projects RFC - this intentionally lands as one vertical feature PR: splitting the manifest, trust boundary, session contract, and UI would leave partial states that are not independently useful or safe to ship - the two open repository-wide Dependabot alerts are transitive development dependencies inherited from the base lockfile and are being handled by dedicated PRs #7766 and #7767; this PR does not modify dependency manifests - CHANGELOG.md is intentionally untouched; release notes remain release-PR owned

@kyleseaman
kyleseaman requested a review from a team August 31, 2026 02:37
@kyleseaman
kyleseaman requested a review from a team as a code owner August 31, 2026 02:37
@kyleseaman
kyleseaman requested a review from dwu96 August 31, 2026 02:38
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — 🔴 changes requested (blocking)

GPT 5.6 found at least one blocking issue that must be resolved before merging c5c308a64d42ab873cf46ddb5b884dfc688a617c. Adjudication emitted 0 well-formed verdict line(s) for total=1, so GPT's verdict stands.

This comment is updated in place on each push.

BLOCKING -- website/src/pages/ProjectBundlesPage.tsx:116 -- Project failures bypass the required error surface
<div ... role="alert">
Failed Project requests, manifest loads, or list loads -> handwritten alerts render -> structured error context and agent hand-off are lost.
Anchor: errors-use-error-notice
Fix: Use ErrorNotice for all three forms; enable askAgent except beside unsaved drafts, with the required no-hand-off comment.
[BLOCK-MERGE] c5c308a
[GPT-REVIEWED] c5c308a

Adjudication (Opus 4.8) — is blocking on each finding proportionate?

The finding anchors to errors-use-error-notice, which carries blocking: true (AUTOSDE.yaml:527). The named code at ProjectBundlesPage.tsx:116 is a hand-written role="alert" danger box (the RequestError component), exactly what the rule forbids ("Never … a bare role="alert" box"). The same pattern recurs at lines 211 and 493. This is anchored to a blocking AUTOSDE rule whose flag is authoritative and outranks my weighing.

Harm rung: N/A — anchored to a blocking: true AUTOSDE rule; not weighed.
Confirmed condition: hand-written role="alert" error box at ProjectBundlesPage.tsx:116, matching a rule that carries blocking: true at website/AUTOSDE.yaml:527.
Real fix cost: swap three hand-written surfaces for ErrorNotice with askAgent — irrelevant here, since a blocking rule's flag is authoritative.

[ADJUDICATION] c5c308a64d42ab873cf46ddb5b884dfc688a617c total=1 uphold=1 downgrade=0
UPHOLD F1 website/src/pages/ProjectBundlesPage.tsx:116 reason=autosde-blocking-rule
[GPT-ADJUDICATED] c5c308a64d42ab873cf46ddb5b884dfc688a617c

False positive or not applicable? A repository writer can comment:
/ai-review override gpt c5c308a64d42ab873cf46ddb5b884dfc688a617c: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5) — 🟡 CONCERNS

UX-level review of c5c308a64d42ab873cf46ddb5b884dfc688a617c — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

UX-Verdict: CONCERNS

Solid, coherent surface — but the remove confirm reassures while it force-deletes session work, and the repair path hides exactly when a project breaks.

Watch

  • Remove confirm undersells the loss. Body says "Folders you added stay on disk. {{productName}} removes only storage it created" — but unregister force-deletes projects/state/<id>, the repository checkouts sessions work in (visible in 05-project-active.png), destroying unpushed agent commits. Occasional action × irreversible work loss × every removal. Fix: name the checkouts — "including its repository checkouts; push or copy any work you want to keep."
  • The New-menu Projects section is gated on healthyProjects.length > 0, including "Manage projects". When a user's only project goes unhealthy, the learned menu section silently vanishes at the moment they need the repair path. Fix: gate on projects.length; list unhealthy projects disabled with the "Unavailable" hint.
  • Create/Add forms require hand-typing an absolute path into a bare Input, while the composer's same job ships ProjectPicker with recent + browse. Typos surface only as post-submit rejection. Fix: reuse ProjectPicker for the folder fields.

Suggestions

  • Subtitle/empty state ("Portable Projects that work locally or through Git.") never says what a Project contains — say "Bundle repositories, agents, skills, and MCP servers into a portable workspace."
  • Rename "Add project" → "Add existing project" so the list-header pair is distinguishable before clicking.
  • In ChatInput, render the bundle chip as a static label rather than a permanently disabled button — disabled controls are unfocusable, so keyboard/AT users can't reach the session's Project name.

[UX-REVIEWED] c5c308a

@github-actions github-actions Bot added the merge conflict Branch has merge conflicts with its base — author must resolve before merge label Aug 31, 2026
Comment thread src/kiro_crew/dashboard/handlers_project.py Fixed
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — 🟡 CONCERNS

Premise-level review of c5c308a64d42ab873cf46ddb5b884dfc688a617c — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All evidence gathered. Producing the review.

First-Principles-Verdict: CONCERNS

Bundle skills get a second, parallel trust store while the updated RFC still names the existing #3551 per-directory grant as the mechanism — plus dead registry surface.

What this change ships

Intent: let one named, credential-free bundle carry repos/agents/skills/MCP so the same working context is usable on any install. ADDITION.

  1. Projects tab under Agent Capabilities: create/register/inspect/sync/remove bundles — justified
  2. Session creation can pick a Project; composer shows Project name, directory chip locks — justified
  3. Owner "Trust and activate" installs namespaced agents/skills/MCP; sync withdraws on digest change — justified; see Watch
  4. kirocrew project CLI group, deliberately no MCP mirror — justified; see Watch
  5. Managed Git clone + fast-forward-only sync — justified
  6. Sessions persist project_id; Project view lists live/historical sessions — justified
  7. New /api/project-bundles namespace; Task Runner keeps /api/projects untouched — justified
  8. CI E2E harness opts its throwaway home into the existing sandbox_allow_unsandboxed_exec key — declared, justified
  9. RFC + module specs updated in-commit — mandated by AGENTS.md
  10. scripts/refresh-playwright-cookies.py reformat — rides along, undeclared, formatting-only

Watch

  • Skills trust now has two spellings. skill_trust.grant_project_trust (src/kiro_crew/skill_trust.py:523) already provides expected-key-reviewed, critically-audited consent for skills in a project directory; this diff references it 0 times (grepped grant_project_trust) and builds a separate digest-bound store under trust/project-bundles/. The revised RFC still says bundle context "passes through the same per-directory trust grant … (Support project-level .kiro/ configuration (agents, MCP, steering) in Crew dashboard #3551 machinery)" — spec text and shipped mechanism disagree in the same commit, and a workspace.source: self bundle puts its skills/ where the older grant may reach the same content without the digest binding.
  • AGENTS.md says the MCP-first rule has "exactly one deliberate exception" (kirocrew computer call); the RFC now names kirocrew project as a second. The counted-exception sentence goes stale unfixed.

Subtractions

  • Delete ProjectRegistry.refresh() (src/kiro_crew/project_registry.py) — 0 call sites in the entire diff, production or test (grepped refresh(); GitProjectStore.sync already refreshes display metadata via add_managed.
  • Shrink ProjectAttachment to project_id/workspace_dir/briefname, bundle_dir, and repositories have 0 production consumers (grepped attachment\.; only tests read them); the brief string already carries the repo paths sessions use.
  • Fold ProjectCapabilityManager.withdraw() into deactivate() — 1 caller (project_capabilities.py:4440), a generalized public method for one internal use.

[FIRST-PRINCIPLES-REVIEWED] c5c308a

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed c5c308a64d42ab873cf46ddb5b884dfc688a617c — this comment is updated in place on each push.

Review details

The candidate is statically accurate: _ProjectMcpSourceChanged(RuntimeError) can escape rebuild_agent_config, and the CLI's except tuple omits RuntimeError. But I verified that project_mcp_source_changed(kirocrew_mcp, current_project_source) compares two reads of the same file (_user_dir()/mcp.json, at line 3806 and 4639), and rebuild_agent_config never writes that file itself. So in the absence of a concurrent writer the comparison is always equal → no retry, no raise. Reaching the raise requires the Project source file to be rewritten with different Project-marked entries twice — once during the initial pass and again during the single internal retry — by a concurrent dashboard activate/deactivate, each precisely timed within one sync rebuild. That is a "could-happen" double-race, not a condition I can re-derive as occurring in practice at 80+, and the outcome (a traceback instead of a clean Project error: on that rare collision) is neither data loss nor a security boundary. Falsification condition (a) fails. Dropped.

No grounded Step 2 finding surfaced while verifying.

No findings.

[OPUS-REVIEWED] c5c308a

Verdict parsed from the review's SHA-scoped output markers for commit c5c308a64d42ab873cf46ddb5b884dfc688a617c.

False positive or not applicable? A repository writer can comment:
/ai-review override fable c5c308a64d42ab873cf46ddb5b884dfc688a617c: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — 🟡 CONCERNS

Design-level review of c5c308a64d42ab873cf46ddb5b884dfc688a617c — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All three investigations are complete. The trust core is sound (digest-bound trust, materialize-by-copy, namespaced install, revoke-on-digest-change, uniform runtime governance — no bypass), specs and RFC were genuinely updated, and shared infrastructure was reused rather than forked. Three design-level risks survived the kill-filter: a manifest field that escapes the review digest, a portable format with no in-v1 extension path, and a trust confirmation that attests to content the UI never shows.

Design-Verdict: CONCERNS

Trust core is sound, but workspace_source escapes the review digest and the portable v1 manifest has no designed extension path.

Watch

  • _capability_review_key (project_capabilities.py:454–473) digests sources and context but omits manifest.workspace_source, so a sync can re-point the session working directory among declared repos without withdrawing trust — the one behavioral manifest field outside the key. Fold it into the declaration digest.
  • The portable format is fail-closed by strict equality everywhere: unknown context keys are fatal (project_manifest.py:258–263), registry/activation stores are v1-only with no migration hook, and the RFC's own example manifest (context.steering, workflows, pinned) is not v1-loadable. Any additive field hard-forks portability between installs of different ages — decide the extension posture before bundles circulate.
  • Owner trust binds a digest over agent prompts and skill trees the review UI never renders (only counts, names, and MCP commands — handlers_project.py:231–251); the owner attests to bytes unseen. Not a bypass, but the consent is thinner than the ceremony implies.

Suggestions

  • Give the shared mcp.json lock a public owner instead of importing _mcp_lock privately from apps/bridges (project_capabilities.py:1206) — this PR extends an already-orphaned pattern.
  • Fix the RFC example manifest to be v1-loadable and fill implementation-prs.

[DESIGN-REVIEWED] c5c308a

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from f7c851a to f507017 Compare August 31, 2026 12:47
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Aug 31, 2026
Comment thread src/kiro_crew/dashboard/handlers_project.py Fixed
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from f507017 to d27d891 Compare August 31, 2026 13:07
@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running merge conflict Branch has merge conflicts with its base — author must resolve before merge labels Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from d27d891 to 58b940a Compare August 31, 2026 13:43
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from 58b940a to 32c0682 Compare August 31, 2026 14:11
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 31, 2026
@github-actions github-actions Bot added the readiness: action required A blocking check or review needs attention label Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from 8ac397b to e08705a Compare August 31, 2026 21:41
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch from e08705a to 5d1db8e Compare August 31, 2026 22:21
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Aug 31, 2026
@kyleseaman
kyleseaman force-pushed the feat/project-bundles branch 2 times, most recently from 0585f7c to add0611 Compare August 31, 2026 23:44
@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 1, 2026
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 1, 2026
@kyleseaman

Copy link
Copy Markdown
Collaborator Author

/ai-review override gpt 485cdce: Editable metadata is restricted to the owner-only editor and intentionally preserves original values so partial saves cannot persist redaction markers; display fields stay redacted and the regression test pins this contract.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Human judgment recorded

@kyleseaman marked the gpt AI finding as false positive, not applicable, or explicitly accepted for 485cdce2ae4c9e2fc2259eff3cad1a49f6608e4c.

Editable metadata is restricted to the owner-only editor and intentionally preserves original values so partial saves cannot persist redaction markers; display fields stay redacted and the regression test pins this contract.

This decision applies only to this commit. A new push requires a new judgment.

@bolichen97

Copy link
Copy Markdown
Collaborator

Open PR relationship audit

This is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion.

Relationship findings

  • This PR is OVERLAPPING with PR #1515. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. Independent features (containerized agent execution vs. portable Project attachment) sharing the slot class and the composer shelf. Neither subsumes the other. Files: src/kiro_crew/dashboard/state.py, website/src/components/ChatInput.tsx. The two independent directions used different labels; the matrix conservatively retains OVERLAPPING for coordination.
  • This PR is OVERLAPPING with PR #3139. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. Different user goals — parallel sessions on one repository via git worktrees versus a portable multi-repo context bundle — that touch the same slot-metadata seam. Both can ship; whichever lands second resolves a mechanical conflict in five files. Files: src/kiro_crew/dashboard/state.py, src/kiro_crew/history.py, src/kiro_crew/dashboard/chat_handlers.py, src/kiro_crew/dashboard/chat_persistence.py.
  • This PR is OVERLAPPING with PR #3987. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. Complementary halves of multi-repo work: 7181 supplies and names the repositories, 3987 makes git status legible across them. Worth a note on 7181 that Project sibling checkouts stay outside the Git panel until 3987 (or an equivalent) lands. Files: src/kiro_crew/dashboard/handlers/files.py, website/src/api/client.ts.
  • This PR is OVERLAPPING with PR #4736. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. The merged per-directory consent path covers only capabilities that live in the working directory of the session that is using them. 7181 covers capabilities that travel with a portable bundle, which the merged code cannot express. Files: src/kiro_crew/skills.py.
  • This PR is OVERLAPPING with PR #7693. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. Unrelated capabilities (running a session on a connected remote crew vs. attaching a portable Project) that extend the same three slot-contract structures. No behavioral collision, only a merge-order conflict. Files: src/kiro_crew/dashboard/slot_projection.py, src/kiro_crew/history.py, test/test_chat_slot_facade_contract.py.
  • This PR is OVERLAPPING with PR #7715. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #7181: KEEP. Distinct fixes on one shared field, mutually reinforcing rather than redundant. No duplicated code. Files: src/kiro_crew/dashboard/chat_runner.py.
  • PR #8307 is OVERLAPPING relative to this PR. The goals differ or the implementations can complement each other; this is not a duplicate claim. Recommended action for PR #8307: MERGE_DISCUSSION. Different features (portable project bundles vs per-crew template forks) that collide on three specific code sites, including one assertion whose merged form must account for the new boolean field. Keep both; sequence the merges and fix the shared assertion in whichever lands second. Files: test/test_agent_discovery.py, src/kiro_crew/agent_discovery.py, src/kiro_crew/agent.py.

No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit.

Add local and Git-backed Projects that bundle repositories, agents, skills, and MCP configuration. Integrate Projects with session creation and expose the experience under Agent Capabilities.
@NicholasRBowers

Copy link
Copy Markdown
Contributor

🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca]: This PR has been inactive for 7+ days. I reviewed the blockers but they require your input:

  • Scale: 11,880 additions across 95 files introducing a new subsystem (portable project bundles) — this exceeds the pipeline's safety threshold for automated fixes (>3000-line new subsystem), so automation will not resolve the merge conflicts or drive review rounds here; conflict resolution across that surface needs the author's design intent.
  • Merge conflict with current main needs a rebase by someone who owns the design.
  • GPT blocking finding is anchored to the blocking: true AUTOSDE rule errors-use-error-notice: website/src/pages/ProjectBundlesPage.tsx renders hand-written role="alert" boxes at lines 116, 211 and 493 instead of ErrorNotice — mechanical to fix, but it belongs in the same pass as the rebase.
  • Frontend Tests (2) / Frontend Coverage Merge / Coverage Gate reds should be re-checked after the rebase (stale Sep-4 base).

When you've addressed these, the pipeline will re-assess on its next cycle.

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

Labels

merge conflict Branch has merge conflicts with its base — author must resolve before merge needs-author-decision PR blocked on author input readiness: action required A blocking check or review needs attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants