feat: export native AI-DLC workspaces - #403
Conversation
21b5173 to
877ff40
Compare
JWThewes
left a comment
There was a problem hiding this comment.
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.
| // 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 }); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
| const exported = await createNativeExport({ | ||
| s3, | ||
| bucket: ARTIFACTS_BUCKET(), | ||
| upstreamRef: meta.aidlcRepoRef || AIDLC_REPO_REF(), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| (meta.repos ?? []).map((repository) => { | ||
| const provider = meta.repoProviders?.[repository] || meta.gitProvider || 'github'; | ||
| return { | ||
| name: repositoryName(repository), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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', |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Addressed in 86cd45a:
frontend/src/pages/IntentView.tsx:222opens the dialog when warnings exist, even without setup instructions.frontend/src/components/intent/NativeExportSetupDialog.tsx:119renders every warning in the amber alert. Lines 109–115 provide warning-only title/description.
| </AlertDialog> | ||
|
|
||
| <AlertDialog | ||
| open={constructionExport !== null} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Addressed in 86cd45a, creation of the NativeExportSetupDialog
|
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. |
Summary
Native workspace export
*-questions.mdfiles from human gates when no persisted Markdown artifact exists.stage-graph.json, andscope-grid.json.Version and snapshot fidelity
aidlc-docs/and neweraidlc/spaces/...workspace layouts by inspecting the selected harness.Platform integration
User experience
Verification
ba0cfe999856033ecb909a9135b46fe10811bf55) and a multi-repo space with newer version (83ed7a812c4024904f2c5e4d744e28077e0a5acd)Fixes #400