-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add agent-native workspace bootstrap #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
21d9d81
feat: add agent-native workspace bootstrap
chasechou007 a14ecdb
fix: constrain managed agent paths
chasechou007 f615720
fix: reconcile managed adapter state
chasechou007 29c3aa5
fix: validate managed read boundaries
chasechou007 5ec99a7
fix: unify config path inspection
chasechou007 bf96d98
fix: preserve managed file permissions
chasechou007 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
opendomain/candidates/candidate-0012-agent-native-project-adoption.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| --- | ||
| type: domain_candidate | ||
| id: candidate-0012-agent-native-project-adoption | ||
| status: proposed | ||
| proposed_change_type: add_rule | ||
| target: | ||
| type: business_rule | ||
| id: opendomain.project-adoption-must-not-require-host-package-manifest | ||
| confidence: high | ||
| extracted_by: codex | ||
| extracted_at: 2026-08-03 | ||
| evidence: | ||
| - type: human_review | ||
| location: README.zh-CN.md | ||
| summary: The maintainer requires OpenDomain adoption to avoid forcing npm scripts or a package.json into host projects. | ||
| confidence: high | ||
| - type: code | ||
| location: src/init.mjs | ||
| summary: Project initialization creates canonical semantic and Agent integration files without modifying host package metadata. | ||
| confidence: high | ||
| - type: test | ||
| location: tests/agent-workspace.test.mjs | ||
| summary: Conformance tests require Codex integration to initialize and update without creating package.json or package-lock.json. | ||
| confidence: high | ||
| possible_conflicts: | ||
| - The OpenDomain CLI is still distributed through npm and requires a user-level Node.js runtime until standalone binaries are released. | ||
| - Agent-specific repository files remain necessary even though host language package metadata is not. | ||
| - Homebrew and standalone binary delivery are separate changes and have not yet provided external adoption evidence. | ||
| review: | ||
| state: proposed | ||
| suggested_reviewer: opendomain-maintainer | ||
| --- | ||
|
|
||
| # Candidate: Agent-native Project Adoption | ||
|
|
||
| ## Proposed Rule | ||
|
|
||
| Adopting OpenDomain in a project must not require that project to create or | ||
| modify a package manifest, package-manager lockfile, or npm script. Runtime | ||
| installation belongs to the user's tool environment; the project contains only | ||
| canonical OpenDomain sources and explicitly selected repository-local Agent | ||
| integration files. | ||
|
|
||
| ## Agent Workflow Meaning | ||
|
|
||
| Humans should be able to state their goal in natural language. Agent adapters | ||
| select deterministic OpenDomain CLI operations for exploration, modeling, | ||
| Candidate review, and implementation grounding. Direct CLI commands remain | ||
| available for CI, debugging, and advanced use, but they are not the primary | ||
| human workflow. | ||
|
|
||
| ## Requested Human Review | ||
|
|
||
| Keep this rule proposed until the Codex bootstrap, standalone binary, Homebrew | ||
| installation, and at least one external project adoption confirm that a | ||
| package-manager-neutral project workspace remains practical across upgrades. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "https://opendomain.dev/schemas/workspace-config.schema.json", | ||
| "title": "OpenDomain Workspace Integration Configuration v1", | ||
| "type": "object", | ||
| "required": ["schema_version", "agent_integration"], | ||
| "properties": { | ||
| "schema_version": { | ||
| "const": "1" | ||
| }, | ||
| "agent_integration": { | ||
| "type": "object", | ||
| "required": ["adapter_version", "tools"], | ||
| "properties": { | ||
| "adapter_version": { | ||
| "type": "string", | ||
| "pattern": "^[1-9][0-9]*$" | ||
| }, | ||
| "tools": { | ||
| "type": "array", | ||
| "uniqueItems": true, | ||
| "items": { | ||
| "enum": ["codex"] | ||
| } | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| import { stringify as stringifyYaml } from "yaml"; | ||
|
|
||
| export const AGENT_ADAPTER_VERSION = "1"; | ||
| export const WORKSPACE_CONFIG_SCHEMA_VERSION = "1"; | ||
| export const SUPPORTED_AGENT_TOOLS = Object.freeze(["codex"]); | ||
|
|
||
| const CODEX_SKILLS = Object.freeze([ | ||
| Object.freeze({ | ||
| name: "opendomain-explore", | ||
| description: "Explore accepted OpenDomain semantics and Candidate boundaries without changing the domain model.", | ||
| body: `Explore the project's OpenDomain model without mutating it. | ||
|
|
||
| 1. Run \`opendomain validate\` before relying on workspace sources. | ||
| 2. Use \`opendomain ids list\` or the semantic index to find the smallest relevant accepted sources. | ||
| 3. Read accepted concepts, rules, lifecycles, events, and their evidence. | ||
| 4. Keep every Domain Candidate visibly separate from accepted knowledge. | ||
| 5. Report gaps or conflicts; do not silently resolve or promote them. | ||
| ` | ||
| }), | ||
| Object.freeze({ | ||
| name: "opendomain-model", | ||
| description: "Build or refine an OpenDomain model while keeping inferred knowledge in Candidate form until human review.", | ||
| body: `Build or refine the project's long-lived domain model. | ||
|
|
||
| 1. Separate stable business semantics from delivery intent and implementation details. | ||
| 2. Read existing accepted sources and evidence before proposing changes. | ||
| 3. Record uncertain, inferred, or conflicting knowledge as a Domain Candidate first. | ||
| 4. Run \`opendomain validate\` after changing OpenDomain files. | ||
| 5. Never accept a Candidate without an explicit human review decision. | ||
| ` | ||
| }), | ||
| Object.freeze({ | ||
| name: "opendomain-review", | ||
| description: "Review OpenDomain Candidates with evidence and conflicts while preserving explicit human decision ownership.", | ||
| body: `Review a Domain Candidate without treating it as accepted truth. | ||
|
|
||
| 1. Use \`opendomain candidate show <candidate-id>\` to inspect the proposal. | ||
| 2. Read its evidence, target, confidence, conflicts, and existing accepted sources. | ||
| 3. Explain compatibility impact and unresolved uncertainty to the human reviewer. | ||
| 4. Invoke \`opendomain candidate review\` only after the human explicitly chooses a decision, reviewer, and reason. | ||
| 5. Run \`opendomain validate\` after a review mutation. | ||
| ` | ||
| }) | ||
| ]); | ||
|
|
||
| export function workspaceConfigTemplate(tools = []) { | ||
| return stringifyYaml({ | ||
| schema_version: WORKSPACE_CONFIG_SCHEMA_VERSION, | ||
| agent_integration: { | ||
| adapter_version: AGENT_ADAPTER_VERSION, | ||
| tools | ||
| } | ||
| }, { lineWidth: 0 }); | ||
| } | ||
|
|
||
| export function managedAgentsTemplate() { | ||
| return `<!-- opendomain:managed:start --> | ||
| ## OpenDomain | ||
|
|
||
| This repository uses OpenDomain for long-lived business semantics. | ||
|
|
||
| Before implementing a non-trivial change with an applicable Source Unit, run: | ||
|
|
||
| \`\`\`bash | ||
| opendomain assure <source-unit> | ||
| \`\`\` | ||
|
|
||
| Read every accepted source listed in \`grounding_pack.read_first\`. Treat | ||
| \`grounding_pack.candidate_boundaries\` as proposed knowledge, never accepted | ||
| truth. Report the accepted IDs and Candidate boundaries used when completing | ||
| the task. | ||
|
|
||
| AI-inferred domain knowledge starts as a Domain Candidate. Human reviewers own | ||
| acceptance, rejection, risk decisions, and final validation. | ||
| <!-- opendomain:managed:end --> | ||
| `; | ||
| } | ||
|
|
||
| export function agentSkillResources(tools = []) { | ||
| if (!tools.includes("codex")) { | ||
| return []; | ||
| } | ||
|
|
||
| return allAgentSkillResources(); | ||
| } | ||
|
|
||
| export function allAgentSkillResources() { | ||
| return CODEX_SKILLS.map((skill) => ({ | ||
| path: `.codex/skills/${skill.name}/SKILL.md`, | ||
| content: `--- | ||
| name: ${skill.name} | ||
| description: ${skill.description} | ||
| compatibility: Requires the opendomain CLI. | ||
| metadata: | ||
| generatedBy: opendomain | ||
| adapterVersion: "${AGENT_ADAPTER_VERSION}" | ||
| --- | ||
|
|
||
| ${skill.body}` | ||
| })); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import { randomUUID } from "node:crypto"; | ||
| import { lstat, open, rename, rm } from "node:fs/promises"; | ||
|
|
||
| export async function atomicWriteUtf8(file, content) { | ||
| const temporary = `${file}.opendomain-${process.pid}-${randomUUID()}.tmp`; | ||
| const existingMode = await regularFileMode(file); | ||
| let handle = null; | ||
|
|
||
| try { | ||
| handle = await open(temporary, "wx", existingMode ?? 0o666); | ||
| await handle.writeFile(content, { encoding: "utf8" }); | ||
| if (existingMode !== null) { | ||
| await handle.chmod(existingMode); | ||
| } | ||
| await handle.close(); | ||
| handle = null; | ||
| await rename(temporary, file); | ||
| } catch (error) { | ||
| await handle?.close().catch(() => {}); | ||
| await rm(temporary, { force: true }).catch(() => {}); | ||
| throw error; | ||
| } | ||
| } | ||
|
|
||
| async function regularFileMode(file) { | ||
| try { | ||
| const fileStat = await lstat(file); | ||
| if (!fileStat.isFile()) { | ||
| throw new Error(`Atomic write target '${file}' is not a regular file.`); | ||
| } | ||
| return fileStat.mode & 0o7777; | ||
| } catch (error) { | ||
| if (error.code === "ENOENT") { | ||
| return null; | ||
| } | ||
| throw error; | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.