Skip to content

feat: export native AI-DLC workspaces - #403

Open
jeromevdl wants to merge 18 commits into
mainfrom
feat/workflow-exporter
Open

feat: export native AI-DLC workspaces#403
jeromevdl wants to merge 18 commits into
mainfrom
feat/workflow-exporter

Conversation

@jeromevdl

@jeromevdl jeromevdl commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Native workspace export

  • Export a stable Collaborative AI-DLC checkpoint as a runnable native AI-DLC workspace for Claude, Codex, Kiro CLI, Kiro IDE, or OpenCode.
  • Reconstruct native State Version 7 with the workflow scope, completed and skipped stages, and the correct resume point.
  • Materialize generated Markdown work products in their canonical native phase, stage, and per-unit paths.
  • Reconstruct pending and answered *-questions.md files from human gates when no persisted Markdown artifact exists.
  • Preserve arbitrary custom workflow compositions by registering their native scope definition, stage frontmatter, stage-graph.json, and scope-grid.json.
  • Include custom project rules and repository URL/branch metadata. Source code and credentials are intentionally excluded.
  • Reconstruct multi-unit Construction state: complete Bolt DAG, merged-unit receipts, autonomy mode, and next-unit resume point.
    • Reconstruct native audit stage events and runtime-graph.json.

Version and snapshot fidelity

  • Resolve the native harness from the intent's pinned AI-DLC commit, fetch it on demand, and cache the immutable archive in S3.
  • Support both legacy aidlc-docs/ and newer aidlc/spaces/... workspace layouts by inspecting the selected harness.
  • Preserve pinned stage versions and compatibility with legacy workflow snapshots.
  • Detect whether the pinned harness ships aidlc-workspace-sync.ts; otherwise provide manual sibling-repository setup.
  • Use the root Terraform AI-DLC pin consistently across Lambdas.

Platform integration

  • Add the export API, archive generation, presigned downloads, S3 lifecycle cleanup, IAM permissions, and deployment support.
  • Increase export Lambda capacity for uncached harness retrieval.

User experience

  • Add a workspace download action with harness selection:
image
  • Warn that subsequent local work will not synchronize back into Collaborative AI-DLC traceability:
image
  • Provide post-download repository and workspace setup commands when the exported checkpoint is entering Construction or a later phase:
image

Verification

  • pre-commit hook: 125 test files, 2,490 tests passed
  • frontend production build passed
  • intents Lambda build passed
  • frontend lint and formatting checks passed
  • intents lint and formatting checks passed
  • Add native runtime recompilation checks against pinned 2.3.3 and current v2, see screenshots.
  • Tested live against "legacy" AIDLC (ba0cfe999856033ecb909a9135b46fe10811bf55) and a multi-repo space with newer version (83ed7a812c4024904f2c5e4d744e28077e0a5acd)

Fixes #400

@jeromevdl
jeromevdl marked this pull request as ready for review August 13, 2026 15:21
@jeromevdl
jeromevdl force-pushed the feat/workflow-exporter branch from 21b5173 to 877ff40 Compare August 13, 2026 15:24

@JWThewes JWThewes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The feature direction looks useful, but I think the checkpoint and provenance guarantees need tightening before this is safe to merge. The inline comments cover the concrete changes I am asking for.

Comment thread lambda/intents/index.js Outdated
// while the archive is assembled, producing an internally inconsistent
// checkpoint.
if (intentId && httpMethod === 'POST' && path?.endsWith('/export')) {
const records = await store.getExecutionRecords(intentId, { includeOutputs: false });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This status check does not actually make the export a stable snapshot. We read the execution partition here, then resolve the plan and read Neptune artifacts later; a WAITING intent can be answered or edited in between. That can give us old stage/question state with newer artifacts in the same ZIP. Can we either export from an immutable revision, or capture and recheck a revision/status token immediately before upload and fail or retry if anything changed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will create some immutable checkpoints at the end of each stage, so that it will also permit the export while in status RUNNING (exporting the latest stable checkpoint).

@jeromevdl jeromevdl Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 5a75ccf by introducing lightweight immutable workflow checkpoints at completed stage boundaries. Checkpoints reference content-addressed artifact versions rather than storing ZIPs or artifact bodies. RUNNING exports use the latest checkpoint, while WAITING and terminal exports use live state with a final consistency recheck. This also enables safe exports during active execution without mixed snapshots.

Comment thread lambda/intents/index.js
const exported = await createNativeExport({
s3,
bucket: ARTIFACTS_BUCKET(),
upstreamRef: meta.aidlcRepoRef || AIDLC_REPO_REF(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I do not think meta.aidlcRepoRef is an execution pin yet. We persist it at intent creation and use it here, but AgentCore still reads the deployment-wide AIDLC_REPO_REF; after a pin update an existing intent can continue under the new ref and then export the old harness. Please thread the intent's ref through execution and preserve matching block/workflow snapshots, or record the actual ref per stage and reject mixed-ref exports.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 47d71f8. aidlcRepoRef is now an execution pin, not only an export pin. The intent’s resolved SHA and exact supporting block versions are stored on META, forwarded through orchestration, and used by AgentCore for the conductor and methodology library. Stage rows record the effective SHA, and export rejects mixed-revision executions. This covers parked sessions that resume on a newer AgentCore image.

Comment thread lambda/intents/index.js Outdated
(meta.repos ?? []).map((repository) => {
const provider = meta.repoProviders?.[repository] || meta.gitProvider || 'github';
return {
name: repositoryName(repository),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We lose the canonical repository identity here. org-a/api and org-b/api are both valid project repositories, but both become api, so repos.json and the setup commands target the same directory. The reverse-engineering projector has the opposite problem and rejects owner/repo as a path segment. Could we keep owner/repo as the ID and derive a collision-safe local directory name once, then use that mapping everywhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 0871912. Exports now preserve canonical repository IDs and derive one deterministic local directory mapping. Unique basenames remain unchanged; collisions such as org-a/api and org-b/api become org-a_api and org-b_api. The same mapping is used by repos.json, intent metadata, CodeKB paths, the export API, and frontend clone commands. Regression tests cover the duplicate-basename case.

};

const loadDistribution = async ({ s3, bucket, upstreamRef, harness }) => {
if (!isCommitSha(upstreamRef)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

aidlc_repo_ref is documented and implemented elsewhere as SHA, tag, or branch, so this makes export fail for an otherwise supported deployment configuration. If export requires immutability, can we resolve the configured ref to a full SHA when the intent is created and persist that SHA, rather than rejecting tags and branches here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 47d71f8. Configured tags and branches are resolved to a full commit SHA before intent creation and seeding. The immutable SHA is then used consistently for runtime snapshots, execution, checkpoints, and native export.
Manually verified with v2.3.0: META, the running stage, and export-manifest.json all used 29a31f7899731b53f2b8d7f76cd223f9a8a25859.

batches: parsed.batches,
skipMatrix: unitPlan.skipMatrix ?? {},
walkingSkeleton: unitPlan.walkingSkeleton ?? null,
autonomyMode: hasRecordedAutonomyMode ? unitPlan.autonomyMode : 'gated',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This changes workflow semantics by making a choice the user has not made. In cloud state, autonomyMode is intentionally null until the post-skeleton ladder; defaulting it to gated also causes us to emit an AUTONOMY_MODE_SET audit event that never happened. Please preserve unset and let the native workflow ask the ladder question.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 486a420. I had some issues with Kiro when letting unset, it didn't ask for the autonomy mode.

setExporting(true);
setActionError(null);
try {
const result = await intentsService.exportWorkflow(projectId, intentId, harness);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The API returns warnings specifically for provenance and runtime compatibility, but we never surface result.warnings here. In the no-setup case the user will not see them at all. Can we show warnings before or alongside the download, and add a test for the legacy-ref warning?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 86cd45a:

  • frontend/src/pages/IntentView.tsx:222 opens the dialog when warnings exist, even without setup instructions.
  • frontend/src/components/intent/NativeExportSetupDialog.tsx:119 renders every warning in the amber alert. Lines 109–115 provide warning-only title/description.

Comment thread frontend/src/pages/IntentView.tsx Outdated
</AlertDialog>

<AlertDialog
open={constructionExport !== null}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: could we move this setup dialog into a NativeExportSetupDialog component and drive the four modes from shared step data? IntentView is now about 1,000 lines and the extraction, launch, and continue steps are repeated across each branch, which will make future setup changes easy to miss in one mode.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 86cd45a, creation of the NativeExportSetupDialog

@jeromevdl

Copy link
Copy Markdown
Contributor Author

f968f86 adds immutable, commit-pinned methodology catalogs in S3. Seed writes the structured catalog before replacing SYSTEM records, and native export uses the intent’s historical catalog when the current SYSTEM revision differs. Missing catalogs can be rebuilt from the pinned commit. Manually verified with an intent pinned to 83ed7a8… after SYSTEM was reseeded to v2.3.0 (29a31f…); export succeeded and retained 83ed7a8… in the manifest.

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.

[Feature]: Export AIDLC workflow assets for local development

2 participants