Replies: 1 comment
|
Thanks for moving the proposal to Discussions and preserving the original issue. After reviewing the current OPSX workflow and the native AISP architecture more carefully, I think the cleanest direction is to publish this as an externally maintained native AISP skill package, with AISOP providing the executable workflow inside that package. This would not require OpenSpec core, existing OpenSpec skills, or ordinary OpenSpec users to adopt a new dependency. Proposed architectureThe integration would be published as one native AISP skill: The fixed file: would be both:
AISP and AISOP would not be represented as two independent manifests or two competing workflow definitions. The same two-message JSON document would contain: In short: References:
OpenSpec remains authoritativeThe AISP/AISOP integration would not redefine:
Those remain controlled by OpenSpec and its CLI. The AISP skill would only define how an agent reliably performs the existing The intended boundary is: This should not be an OpenSpec community schemaAn OpenSpec community schema defines artifacts, templates, instructions, and dependency relationships. This integration would not define any of those. It would execute whichever OpenSpec schema is currently resolved by the CLI. For that reason, the most accurate classification appears to be:
rather than:
Preserve the OPSX philosophyThe AISOP execution graph should not hardcode a universal sequence such as: OPSX is intentionally fluid and schema-driven. The active OpenSpec schema and current CLI state should always determine which artifacts exist, which are enabled, and which action is valid. The execution model should therefore remain status-driven: AISOP would make the agent-side control flow explicit, but OpenSpec would continue to define the domain workflow. Updating the original proof of conceptThe original proof of concept demonstrated the basic architectural boundary, but a runnable package should now be updated to match the current That includes:
The completion condition should not be: It should be: Proposed native AISP contractThe native package would use an AISP contract similar in structure to: {
"profile": "aisp.skill.v1",
"invocation": {
"mode": "auto_or_manual",
"when_to_use": [
"the user wants to create OpenSpec planning artifacts for a proposed change",
"the user explicitly invokes the OpenSpec propose workflow"
],
"when_not_to_use": [
"the user only wants to explore an idea without creating a change",
"the user wants to implement an existing OpenSpec change",
"the user wants to archive, sync, or verify a change"
]
},
"non_negotiable": [],
"discovery": {
"category": "software-engineering",
"tags": [
"openspec",
"spec-driven-development",
"planning",
"artifact-workflow"
]
},
"risk_level": "medium",
"resources": []
}The complete contract would live directly inside: in It would not be duplicated into Proposed non-negotiable rulesThe package should bind at least the following rules to real execution mechanisms. 1. OpenSpec is authoritativeThis should be enforced by using structured OpenSpec CLI results as runtime state rather than model-generated substitutes. 2. Propose is planning-onlyThis should be enforced through:
3. Existing changes cannot be overwritten silentlyThis should bind to a blocking human interaction such as: 4. Artifact writes are path-confinedThe runtime should compare the actual write target with the OpenSpec-resolved path before allowing the workflow to continue. 5. Dependencies must be read from disk6. Completion requires the full dependency closureThis should bind to a deterministic assertion over normalized OpenSpec status. 7. Errors cannot become success8. Human decisions cannot be simulatedProposed AISOP execution topologyThe executable portion of the same graph TD
start[Receive OpenSpec propose request] --> resolve_context[Resolve OpenSpec root store and schema]
resolve_context --> resolve_request[Resolve change description and name]
resolve_request --> input_clear{Material input clear?}
input_clear -->|no| ask_user[Ask human for clarification]
ask_user --> resolve_request
input_clear -->|yes| inspect_change[Inspect existing change]
inspect_change --> change_exists{Change already exists?}
change_exists -->|yes| confirm_existing[Human selects continue rename or cancel]
change_exists -->|no| create_change[Create OpenSpec change]
confirm_existing --> resolve_change_action[Resolve human decision]
resolve_change_action -->|continue| load_status[Load OpenSpec status]
resolve_change_action -->|rename| resolve_request
resolve_change_action -->|cancel| cancelled[Return cancelled result]
create_change --> load_status
load_status --> normalize_status[Normalize OpenSpec status]
normalize_status --> calculate_required[Calculate transitive required artifact set]
calculate_required --> complete{Required set satisfied?}
complete -->|yes| assert_planning_only[Assert planning-only boundary]
complete -->|no| choose_action{Next valid artifact action?}
choose_action -->|ready artifact| load_instructions[Load OpenSpec artifact instructions]
choose_action -->|conditional bypass| load_instructions
choose_action -->|inconsistent state| handle_error[Report inconsistent OpenSpec state]
load_instructions --> read_dependencies[Re-read dependency artifacts]
read_dependencies --> delegated{Instruction delegates generation?}
delegated -->|yes| invoke_delegate[Invoke declared skill or command]
delegated -->|no| generate_artifact[Generate artifact]
invoke_delegate --> verify_artifact[Verify artifact path and content]
generate_artifact --> verify_artifact
verify_artifact --> load_status
assert_planning_only --> final_status[Load and show final OpenSpec status]
final_status --> end_node((End))
resolve_context -.-> handle_error
inspect_change -.-> handle_error
create_change -.-> handle_error
load_status -.-> handle_error
load_instructions -.-> handle_error
read_dependencies -.-> handle_error
invoke_delegate -.-> handle_error
generate_artifact -.-> handle_error
verify_artifact -.-> handle_error
handle_error --> end_node
cancelled --> end_node
This graph would be the execution topology, while the corresponding
Prefer typed OpenSpec capabilities over unrestricted shell accessA production bridge should ideally expose operations such as: rather than granting the AISOP program a general unrestricted shell and unrestricted filesystem access. The adapter may internally invoke the OpenSpec CLI, but the AISP resource and tool contract should expose only the capabilities required by this skill. AISP package layoutOne possible repository layout is: The normative skill identity would be: The skill folder would be the source of truth.
All execution resources used by the skill would be declared in: Agent Skills compatibilityA same-folder Its purpose would only be to:
It should not duplicate the full contract, execution graph, or function definitions. On a host without an AISP/AISOP-compatible runtime, the sidecar can only provide best-effort guidance. It must not claim the same hard enforcement guarantees as a native runtime. Evidence before requesting catalog inclusionBefore requesting an OpenSpec documentation or community-integration entry, the external package should provide runnable evidence for:
The same cases should produce inspectable runtime traces showing:
Questions for the OpenSpec maintainers
The goal is not to replace OpenSpec, redefine OPSX, or introduce a required dependency. The goal is to package the existing OpenSpec |
Uh oh!
There was an error while loading. Please reload this page.
Note
Moved from issue #1217, originally opened by @optimization2026 on 2026-06-16. Continuing the conversation here in Discussions — the original issue thread (including any comments) stays available at #1217 for the record.
openspec-aisop-community-integration-issue.md
openspec-propose-minimal.aisop.json
[Community Integration Proposal] Minimal AISOP execution graph for the OpenSpec propose workflow
Summary
We created a small proof of concept that expresses the OpenSpec
proposeworkflow as an optional AISOP V1.0.0 execution graph.This proposal does not ask OpenSpec to replace its schemas, CLI, Markdown artifacts, or existing skills. OpenSpec remains the source of truth for:
AISOP is used only as an optional, machine-readable execution layer for the agent workflow.
Motivation
The current OpenSpec propose workflow already contains a real control-flow program:
openspec status --jsonopenspec instructions --jsonapplyRequiresartifact is completeToday this behavior is primarily represented as natural-language skill and command instructions.
The AISOP proof of concept makes the main branch, artifact loop, termination condition, and error path explicit while continuing to call the existing OpenSpec CLI.
Minimal flow
graph TD resolve_request[Resolve request and change name] --> input_clear{Input clear?} input_clear -->|no| ask_user[Ask user for clarification] ask_user --> resolve_request input_clear -->|yes| create_change[Create OpenSpec change] create_change --> load_status[Load OpenSpec status] load_status --> apply_ready{Apply requirements complete?} apply_ready -->|yes| finish[Show final status] apply_ready -->|no| load_artifact[Load next ready artifact] load_artifact --> generate_artifact[Generate and write artifact] generate_artifact --> verify_artifact[Verify artifact file] verify_artifact --> load_status finish --> end_node((End)) create_change -.-> handle_error[Handle error] load_status -.-> handle_error load_artifact -.-> handle_error generate_artifact -.-> handle_error verify_artifact -.-> handle_error handle_error --> end_nodeAISOP file
The following file follows the AISOP V1.0.0 two-message JSON structure and has been structurally validated with the AISOP Python reference implementation.
openspec-propose-minimal.aisop.json[ { "role": "system", "content": { "protocol": "AISOP V1.0.0", "axiom_0": "Human_Sovereignty_and_Wellbeing", "id": "openspec_propose_minimal", "name": "OpenSpec Propose Minimal", "version": "0.1.0", "summary": "Generate the OpenSpec artifacts required before implementation.", "description": "A minimal optional AISOP workflow for OpenSpec propose. OpenSpec remains authoritative for artifact status, instructions, dependencies, templates, and paths.", "flow_format": "mermaid", "loading_mode": "normal", "tools": [ "shell", "filesystem", "user_interaction" ], "params": { "change_request": "string" }, "system_prompt": "Follow OpenSpec CLI output exactly. Never invent artifact paths, templates, dependencies, context, or rules." } }, { "role": "user", "content": { "instruction": "RUN aisop.main", "user_input": "{user_input}", "aisop": { "main": "graph TD\n resolve_request[Resolve request and change name] --> input_clear{Input clear?}\n input_clear -->|no| ask_user[Ask user for clarification]\n ask_user --> resolve_request\n input_clear -->|yes| create_change[Create OpenSpec change]\n create_change --> load_status[Load OpenSpec status]\n load_status --> apply_ready{Apply requirements complete?}\n apply_ready -->|yes| finish[Show final status]\n apply_ready -->|no| load_artifact[Load next ready artifact]\n load_artifact --> generate_artifact[Generate and write artifact]\n generate_artifact --> verify_artifact[Verify artifact file]\n verify_artifact --> load_status\n finish --> end_node((End))\n create_change -.-> handle_error[Handle error]\n load_status -.-> handle_error\n load_artifact -.-> handle_error\n generate_artifact -.-> handle_error\n verify_artifact -.-> handle_error\n handle_error --> end_node" }, "functions": { "resolve_request": { "step1": "Read user_input and any clarification stored in runtime state. Return a structured result containing a concise change_description and a kebab-case change_name.", "output_mapping": "change_request", "constraints": [ "Do not invent a change when the request is missing or critically ambiguous.", "change_name must use lowercase letters, digits, and hyphens only." ] }, "input_clear": { "step1": "Return exactly 'yes' if change_request contains both a clear change_description and a valid change_name; otherwise return exactly 'no'." }, "ask_user": { "step1": "sys.io.input('What change do you want to work on? Describe what you want to build or fix.') -> clarification", "step2": "sys.state.set('clarification', clarification)" }, "create_change": { "step1": "Run `openspec new change <change_name>` using change_request.change_name.", "step2": "If the change already exists, ask the human whether to continue that change; do not overwrite it.", "on_error": { "command_error": "handle_error", "default": "handle_error" }, "constraints": "Let OpenSpec resolve the planning location; do not assume repository-local paths." }, "load_status": { "step1": "Run `openspec status --change <change_name> --json` using change_request.change_name.", "step2": "Parse and return applyRequires, artifacts, planningHome, changeRoot, artifactPaths, and actionContext when present.", "output_mapping": "openspec_status", "retry_policy": { "max_attempts": 2, "correction_prompt": "Re-check the active change name and OpenSpec project context." }, "on_error": { "command_error": "handle_error", "default": "handle_error" } }, "apply_ready": { "step1": "Return exactly 'yes' if every artifact listed in openspec_status.applyRequires has status 'done'; otherwise return exactly 'no'." }, "load_artifact": { "step1": "Select the first artifact with status 'ready' in openspec_status.artifacts.", "step2": "Run `openspec instructions <artifact-id> --change <change-name> --json`.", "step3": "Read every completed dependency file returned by the instructions.", "step4": "Return artifact ID, resolvedOutputPath, template, instruction, context, rules, and dependency contents.", "output_mapping": "artifact_job", "retry_policy": { "max_attempts": 2, "correction_prompt": "Reload status and use only OpenSpec-resolved artifact data." }, "on_error": { "command_error": "handle_error", "io_error": "handle_error", "default": "handle_error" }, "constraints": [ "Use resolvedOutputPath instead of assuming a path.", "Treat context and rules as constraints, not output content." ] }, "generate_artifact": { "step1": "Generate the artifact using artifact_job.template and artifact_job.instruction.", "step2": "Apply artifact_job.context and artifact_job.rules as mandatory constraints.", "step3": "Use artifact_job dependency contents as source context.", "step4": "Write only the artifact content to artifact_job.resolvedOutputPath.", "on_error": { "io_error": "handle_error", "default": "handle_error" }, "constraints": [ "Do not copy OpenSpec context or rules blocks into the artifact.", "Do not skip required template sections.", "Do not write outside resolvedOutputPath." ], "execute_mode": "agent" }, "verify_artifact": { "step1": "Verify that artifact_job.resolvedOutputPath exists and is non-empty.", "step2": "Confirm that the generated file follows the returned template structure.", "retry_policy": { "max_attempts": 2, "correction_prompt": "Recreate the artifact at the exact resolved output path." }, "on_error": { "io_error": "handle_error", "assertion_error": "handle_error", "default": "handle_error" } }, "finish": { "step1": "Run `openspec status --change <change-name>` and summarize the created artifacts.", "step2": "Tell the user the change is ready for `/opsx:apply` or the `openspec-apply-change` skill.", "constraints": "Do not claim readiness unless all applyRequires artifacts are complete." }, "handle_error": { "step1": "Report the failed node, available error details, and the last confirmed OpenSpec state.", "step2": "Stop the workflow without claiming completion." }, "end_node": { "step1": "Return the final workflow result." } } } } ]Proposed integration boundary
The workflow depends on the existing OpenSpec commands:
Non-goals
This proof of concept does not propose:
/opsx:*or skill behaviorAIXP-Labs can maintain the integration externally.
Potential benefits
Questions
openspec status --jsonandopenspec instructions --jsonsuitable integration boundaries?AISOP specification:
All reactions