Skip to content

feat(dx): add repository-local GraphForge lifecycle CLIs and project skills #219

Description

@DecisionNerd

Problem

GraphForge has a durable embedded project format and an NPX-distributed agent-workflow package, but it does not yet provide a coherent repository-level developer experience. A developer must currently choose an arbitrary project path, manage Git exclusions manually, call binding APIs for lifecycle operations, and separately understand how workflow manifests relate to project-local agent skills.

This creates avoidable risks:

  • mutable GraphForge generations, locks, transactions, caches, and CURRENT can accidentally enter Git;
  • Python and Node users do not have equivalent one-shot lifecycle commands;
  • repository checkout, GraphForge project state, portable exports, and project-local skills have no explicit boundary;
  • destructive removal and checkpoint restoration lack a CLI safety contract;
  • uvx users may unexpectedly need Node/NPX merely to install the same first-party skills.

Objective

Establish one .graphforge/ namespace for repository-level GraphForge integration and ship equivalent clean-install Python and Node CLI surfaces for safe project lifecycle management, Git hygiene, portable interchange, checkpoint restoration, and project-local agent-skill installation.

The directory has an explicit tracked/untracked boundary:

.graphforge/
├── graphforge.yaml     # tracked project configuration
├── ontology/           # tracked ontology sources
├── schemas/            # tracked schemas and contracts
├── seeds/              # tracked seed recipes/manifests, never materialized data
├── migrations/         # tracked migration definitions
├── imports/            # ignored incoming datasets/project artifacts
├── exports/            # ignored portable project/data artifacts
└── state/              # ignored live project store: FORMAT, CURRENT, generations, locks, cache, ...

There is no second repository convention named graphforge/. GraphForge owns .graphforge/state/, .graphforge/imports/, and .graphforge/exports/ as local data surfaces. The source-controlled portion of .graphforge/ contains definitions and reproducibility metadata only—never graph contents, imported datasets, materialized seed data, snapshots, or exports.

Debt / regime

  • Debt type: development, architecture, documentation, infrastructure/toil, and craft/UX
  • Quality regime: hybrid A/B — deterministic storage and interchange contracts exposed through a developer-facing product workflow

Command contract

Both ecosystems expose the same command names, flags, exit behavior, structured errors, and machine-readable output:

# Python, without a persistent installation
uvx graphforge init
uvx graphforge sync
uvx graphforge export --current --output .graphforge/exports/project.gfportable
uvx graphforge import --input .graphforge/imports/project.gfportable --idempotency-key <uuid>
uvx graphforge checkpoint create before-refactor
uvx graphforge checkpoint list
uvx graphforge revert before-refactor --reason "restore before refactor"
uvx graphforge remove
uvx graphforge skills install
uvx graphforge config validate
uvx graphforge config resolve --json
uvx graphforge infra validate --target production --json

# Node, without a persistent installation
npx @graphforge/cli init
npx @graphforge/cli sync
npx @graphforge/cli export --current --output .graphforge/exports/project.gfportable
npx @graphforge/cli import --input .graphforge/imports/project.gfportable --idempotency-key <uuid>
npx @graphforge/cli checkpoint create before-refactor
npx @graphforge/cli checkpoint list
npx @graphforge/cli revert before-refactor --reason "restore before refactor"
npx @graphforge/cli remove
npx @graphforge/cli skills install
npx @graphforge/cli config validate
npx @graphforge/cli config resolve --json
npx @graphforge/cli infra validate --target production --json

The exact npm package name may change only if registry constraints require it; the documented Python and Node command grammars must remain equivalent.

Architecture Decision Gate

Before implementation, add the next-numbered Proposed ADR under docs/adr/ (currently expected to be ADR 0016) and update both ADR indexes. The ADR must record one durable decision: the repository integration and deployment-configuration boundary for GraphForge.

The ADR must decide and explain:

  • one .graphforge/ namespace rather than separate .graphforge/ and graphforge/ conventions;
  • tracked definitions/reproducibility metadata versus ignored state, imports, exports, materialized seeds, and all actual data;
  • .graphforge/state/ as local engine-owned mutable state, not a Git or IaC deployment artifact;
  • the versioned graphforge.yaml schema and canonical secret-free resolved configuration as the shared contract across Rust, Python, Node, agents, Pulumi, and Terraform;
  • GraphForge ownership of validation, lifecycle semantics, compatibility requirements, and portable deployment-spec rendering versus caller-owned Pulumi/Terraform programs owning provider resources, infrastructure readiness, drift, and teardown;
  • direct native skill installation from parity-checked Python/npm artifacts rather than making Python shell out to NPX;
  • how this decision composes with ADR 0013 project generations, ADR 0014 checkpoints/revert, and ADR 0015 embedded write modes without creating a second persistence or deployment authority.

At minimum, compare these alternatives:

  1. one .graphforge/ namespace with selectively ignored data subdirectories;
  2. separate .graphforge/ runtime and graphforge/ tracked-definition directories;
  3. an entirely ignored .graphforge/ directory plus scattered root-level tracked configuration;
  4. committing or deploying the live GraphForge project directory;
  5. ecosystem-specific configuration/install behavior with Python delegating skills to NPX.

Document positive and negative consequences, migration/compatibility policy, security and secret-handling consequences, Git/worktree behavior, IaC state ownership, and follow-up obligations. Keep implementation detail in this issue; the ADR owns the architectural boundary and rationale. The implementation PR must not mark the ADR Accepted until the decision and its direct contract evidence have passed review.

Requirements

Repository discovery and layout

  • Default to the nearest enclosing Git worktree root when invoked inside one; otherwise default to the current directory.
  • Use <repo>/.graphforge/ as the integration/configuration root and <repo>/.graphforge/state/ as the default live project root.
  • Accept an explicit --project-dir override without assigning special semantics to unrelated directories.
  • Never traverse above the resolved repository/workspace boundary after selection.
  • Reject symlinked project roots, unsafe traversal, foreign non-GraphForge directories, malformed markers, and unsupported future formats without mutation.
  • Treat .graphforge/graphforge.yaml, .graphforge/ontology/, .graphforge/schemas/, .graphforge/seeds/, and .graphforge/migrations/ as tracked project-definition surfaces.
  • Restrict tracked .graphforge/seeds/ content to deterministic recipes, generators, mappings, and source manifests containing stable identities/checksums. Materialized seed rows, copied source datasets, graph contents, Arrow/Parquet files, database files, snapshots, imports, and exports are local data and must be ignored.
  • Treat .graphforge/state/, .graphforge/imports/, and .graphforge/exports/ as ignored local data surfaces. Exporting into the repository must not imply that the artifact should be committed.
  • Do not introduce a second top-level graphforge/ convention.

init

  • Create or idempotently reopen .graphforge/state/ through the public Rust-owned project constructor/bootstrap path.

  • Create the tracked .graphforge/ definition scaffold without overwriting existing configuration, ontology, schemas, seed recipes/manifests, or migrations, and create ignored local data directories only when needed.

  • Verify a real close/reopen/read cycle before reporting success.

  • Add a managed, idempotent block to the repository root .gitignore:

    # GraphForge local project state
    /.graphforge/state/
    /.graphforge/imports/
    /.graphforge/exports/
  • Create .gitignore when absent; preserve encoding, line endings where practical, existing comments, negations, ordering outside the managed block, and unrelated user content.

  • If .graphforge/state/, .graphforge/imports/, .graphforge/exports/, or known GraphForge data-file formats elsewhere under .graphforge/ are already tracked, do not silently alter the Git index. Fail with a bounded remediation message explaining that .gitignore does not untrack files. Tracked definition siblings elsewhere under .graphforge/ are expected and must not cause failure.

  • Detect whether compatible project-local GraphForge skills are present. If absent, install them by default; support --no-skills for callers that explicitly decline.

  • Be idempotent: repeated init must neither duplicate Git-ignore entries nor duplicate marker/knowledge records.

Project-local skills

  • Provide skills install, skills status, skills update, and skills remove operations.
  • Install canonical project-local skills under .agents/skills/ by default, with documented adapters/targets only where an agent host requires a different project-local path.
  • Python must install the same versioned skill assets directly from the Python distribution; it must not spawn npx or require Node.
  • Node must install the same assets directly from the npm distribution.
  • Generate both distributions from one canonical checked-in skill source and test byte/manifest parity to prevent ecosystem drift.
  • Installation must be offline-capable once the selected package is locally available, atomic, idempotent, compatibility-checked against the opened GraphForge format/capabilities, and non-destructive to unrelated skills.
  • Managed skill files must carry enough provenance/version metadata for status and update operations to distinguish pristine managed files from user edits. Never overwrite user-edited files without an explicit conflict resolution flag.
  • Decide and document which installed skill files are intended to be committed. init must not blanket-ignore .agents/skills/.

Declarative configuration and infrastructure as code

  • Define .graphforge/graphforge.yaml with a versioned, closed JSON Schema and canonical resolved JSON representation. Reject unknown fields, invalid combinations, unsupported future versions, unsafe paths, and ambiguous defaults.
  • Make the configuration sufficient to describe named deployment targets and their intended GraphForge topology without embedding provider credentials or secret values. Supported target intent includes:
    • local embedded development/test processes;
    • a local background service or worker;
    • a remote service, worker, job, or host;
    • package/runtime versions and compatibility constraints;
    • storage class/location intent, persistence, backup/checkpoint, resource, concurrency, network, health-check, and observability requirements;
    • declared imports/sources by stable identity and checksum, never copied data payloads in Git.
  • Separate portable GraphForge intent from provider-specific deployment settings. Keep AWS/GCP/Azure/Kubernetes/Docker/host details in explicit target/provider blocks or IaC inputs rather than leaking them into storage/runtime semantics.
  • Provide config validate, config resolve --json, and infra validate --target <name> --json through both Python and Node CLIs. The resolved output must be deterministic, schema-versioned, secret-free, and suitable as an IaC program input.
  • Validate configuration and target compatibility without requiring provisioning, mutation, network access, or access to secret values. When live validation is explicitly requested, report configuration validation separately from connectivity/readiness validation.
  • Publish first-party Pulumi components for the supported TypeScript and Python ecosystems and first-party Terraform module/provider surfaces, generated or contract-tested against the same configuration schema.
  • Pulumi and Terraform must be able to:
    • load or receive the resolved GraphForge target configuration;
    • validate it during preview/plan;
    • render the same canonical provider-neutral deployment specification for local/remote service, worker, job, or host intent;
    • preserve pinned artifact, execution, storage, resource, network, health, observability, backup, source-reference, secret-reference, and capability requirements;
    • distinguish caller-owned infrastructure application from runtime connectivity/readiness/compatibility;
    • materialize no provider resources and invoke no local GraphForge lifecycle command.
  • IaC adapters must pin GraphForge artifact versions/checksums and fail closed on incompatible project, CLI, service, worker, host, or capability versions.
  • Secrets, tokens, credentials, private keys, and sensitive connection material must be passed through Pulumi secret outputs, Terraform sensitive values/provider configuration, environment injection, or the selected secret manager. They must never be written into .graphforge/graphforge.yaml, resolved JSON, state/import/export artifacts, logs, plans, or Git.
  • Portable IaC specification rendering must not read or upload .graphforge/state/ or infer that local mutable state is deployment configuration. Data initialization/import remains an explicit, separately authorized caller operation using external artifact/source references and integrity checks.
  • Define a stable boundary between core lifecycle commands and IaC: GraphForge validates and renders portable intent; caller-owned Pulumi/Terraform programs own infrastructure planning, application, drift, readiness, and teardown.

sync

  • Define sync as reconciling the live GraphForge project from declared repository inputs and the current repository snapshot, not as copying .graphforge/ through Git or synchronizing with a remote GraphForge server.
  • Use explicit, documented configuration or CLI inputs; do not infer actor, operation, provenance, graph, or knowledge identities.
  • Record the exact Git commit when available and whether the worktree was dirty, without embedding unbounded diff contents or secrets.
  • Make unchanged input idempotent and publish changed state through one complete GraphForge generation.
  • Provide --check/dry-run behavior suitable for CI and --json deterministic output suitable for agents.
  • Do not make network access a prerequisite for local synchronization.

export and import

  • Define a versioned, deterministic, portable export envelope distinct from the internal .graphforge/state/ directory layout.
  • Export from one pinned committed generation or named checkpoint and include integrity hashes, project-format/GraphForge compatibility, capability inventory, ontology/configuration state, and provenance needed to validate the artifact.
  • Support deterministic output so identical selected state produces identical bytes, or explicitly isolate and exclude nondeterministic envelope metadata from the content identity.
  • Import only into a new/empty project by default. Require an explicit replace/merge mode if either is supported later; do not invent graph merge semantics in this issue.
  • Validate size bounds, archive paths, symlinks, checksums, supported versions, and capability contracts before mutation.
  • Stage and validate an import before atomically publishing it; failure must leave the previous project generation authoritative.
  • Never treat raw copying of locks, transactions, cache, trash, or a live CURRENT file as portable import/export.

Checkpoints and revert

  • Expose checkpoint create/list/show/delete operations and complete-workspace revert through the existing public checkpoint APIs.
  • revert <checkpoint> must require a non-empty audited --reason, expose the selected checkpoint/current identities through --preview, and require explicit --yes confirmation before mutation.
  • Revert must publish a new complete generation; it must never move CURRENT backward or edit an historical generation.
  • Return deterministic evidence identifying the checkpoint, old current generation, newly published generation, operation, and actor identities.

remove

  • Remove only a positively identified GraphForge project root resolved within the selected repository/workspace.
  • Refuse before mutation unless the caller supplies the explicit --yes confirmation flag; deterministic Python/Node parity does not depend on an interactive prompt.
  • Refuse broad targets such as the repository root, home directory, filesystem root, unresolved variables, or paths outside the selected boundary.
  • Offer/export or create a final checkpoint only as an explicit user choice; do not imply that an internal checkpoint survives deletion of the project directory.
  • Report permanent state deletion accurately. Cross-platform lifecycle semantics do not claim Trash recovery; callers can explicitly export or checkpoint before removal.
  • Preserve the managed GraphForge .gitignore block after state removal so future initialization cannot accidentally stage state, imports, or exports. Ignore-file cleanup is not part of remove.
  • remove deletes .graphforge/state/ only by default. It must not delete tracked .graphforge/ configuration, ontology, schemas, seed recipes/manifests, migrations, ignored imports/exports, project-local skills, repository files, credentials, or unrelated hidden directories.

Cross-ecosystem behavior

  • Rust owns project discovery validation, lifecycle semantics, export/import validation, checkpoint behavior, and destructive-operation safety wherever feasible.
  • Python and Node CLIs remain thin bindings over the same Rust-owned behavior and deterministic result contracts; neither becomes a fallback engine.
  • Commands use stable exit codes and structured {code, message, details} errors, with --json output and no leakage of private paths, payload values, secrets, or native exception text.
  • All mutating commands support clear non-interactive behavior and fail rather than prompt when no TTY is available and required confirmation/identity inputs are missing.

Acceptance Criteria

  • .graphforge/ is documented and tested as the sole repository integration namespace, with tracked definitions separated from ignored state/import/export data and no second graphforge/ convention.
  • The next-numbered repository-integration/deployment-configuration ADR is reviewed and accepted, both ADR indexes are updated, and implementation conforms to its tracked/data, CLI, skills, configuration, and IaC ownership boundaries.
  • uvx graphforge and npx @graphforge/cli expose equivalent init, sync, export, import, checkpoint, revert, remove, and skills lifecycles.
  • init scaffolds tracked .graphforge/ project-definition paths, creates/reopens and verifies .graphforge/state/, installs missing compatible project-local skills by default, and idempotently ignores .graphforge/state/, .graphforge/imports/, and .graphforge/exports/.
  • Git-safe behavior is proven for absent/existing .gitignore, duplicate rules, nested invocation, multiple worktrees, dirty worktrees, already-tracked GraphForge data files, expected tracked .graphforge/ definitions, and unrelated user edits.
  • Automated acceptance proves that initialization, sync, import, export, checkpoint, revert, and remove never add graph contents, source datasets, materialized seeds, Arrow/Parquet/database files, snapshots, imports, or exports to the Git index.
  • Python skill installation has no Node/NPX runtime dependency; Python and npm packages ship parity-checked assets generated from one source.
  • .graphforge/graphforge.yaml has a versioned closed schema and deterministic secret-free resolved JSON consumed identically by the Python CLI, Node CLI, Pulumi components, and Terraform surfaces.
  • Pulumi and Terraform render byte-equivalent canonical deployment specifications for named local/remote service/worker/job/host intent using pinned GraphForge core artifacts without creating provider resources.
  • IaC acceptance proves secrets remain secret/sensitive and absent from Git, resolved configuration, logs, plan output, GraphForge data directories, and exported evidence.
  • IaC apply/drift/destroy acceptance proves GraphForge components change only their provider-neutral state/output projection and never delete repository definitions, local .graphforge/state/, external data, caller infrastructure, or unrelated hosts/services.
  • sync has a documented repository-to-GraphForge contract, records bounded Git identity/provenance, is idempotent on unchanged inputs, and has a CI-safe --check mode.
  • Export/import use a versioned validated portable format and never serialize the live directory as an unsafe raw copy.
  • Revert uses public complete-workspace checkpoint semantics and publishes a new generation with audited evidence.
  • Remove is boundary-checked, explicit-confirmation-gated, reports permanent state deletion accurately, and cannot delete repository inputs, skills, credentials, or unrelated files.
  • Every command has deterministic --json, documented exit codes/errors, Python/Node parity tests, native reopen evidence, and failure-path atomicity tests.
  • User, CLI reference, repository-integration, agent-skills, security, and architecture documentation plus [Unreleased] changelog entries describe the shipped behavior.

BDD Completion Scenarios

Scenario: Initialize a Git repository safely

Given a Git worktree without a GraphForge project or .gitignore
When a developer runs uvx graphforge init or npx @graphforge/cli init
Then the tracked .graphforge/ scaffold and ignored .graphforge/state/ live project are created
And the live project passes a real close/reopen/read verification
And the root .gitignore contains exactly one managed block covering state/, imports/, and exports/
And compatible project-local skills are installed without modifying unrelated repository files.

Scenario: Repeat initialization without churn

Given an initialized project with installed compatible skills and a user-maintained .gitignore
When init runs again from a nested repository directory
Then it resolves the same worktree and project
And produces no duplicate ignore entries, skill files, or GraphForge records
And reports an unchanged/idempotent outcome.

Scenario: Refuse an unsafe Git state

Given .graphforge/state/ content is already tracked or the candidate live project root is a symlink/foreign directory
When initialization or import is requested
Then the command fails before mutation with a stable bounded error
And it does not alter the Git index, foreign directory, or existing GraphForge generation.

Scenario: Round-trip a portable project artifact

Given a pinned committed generation with known capabilities and content
When it is exported and imported into a clean project through either ecosystem CLI
Then integrity and compatibility are validated before publication
And reopening the imported project returns the same deterministic domain results
And no lock, transaction, cache, trash, or live-pointer state is treated as portable data.

Scenario: Revert without rewriting history

Given a named checkpoint and later committed generations
When an authorized caller runs revert with explicit identities and a non-empty reason
Then GraphForge publishes a new complete generation matching the checkpoint outcome
And historical generations and the checkpoint remain immutable
And deterministic evidence identifies the prior current, checkpoint, and new current generations.

Scenario: Remove only local GraphForge state

Given a positively identified .graphforge/state/ project alongside tracked .graphforge/ definitions, ignored imports/exports, and project-local skills
When the developer confirms remove
Then only the selected live project state is explicitly deleted
And tracked inputs, exports, skills, credentials, Git metadata, and unrelated files remain untouched
And permanent deletion is reported accurately without claiming Trash recovery.

Scenario: Validate and render one portable IaC contract

Given a tracked .graphforge/graphforge.yaml with named local and remote targets and secret references but no secret values or data payloads
When a developer runs GraphForge config/infra validation, Pulumi preview, or Terraform plan
Then every surface resolves the same schema-versioned target intent and compatibility constraints
And validation can complete without provisioning or exposing secrets
And every IaC surface renders the same pinned provider-neutral deployment specification without creating a service, transport, or provider resource.

Scenario: Remove the IaC projection without deleting project data

Given Pulumi or Terraform previously recorded a GraphForge deployment specification for a named target
When its destroy operation runs
Then only the GraphForge component or module projection is removed from IaC state
And repository definitions, local GraphForge state, external datasets, portable artifacts, credentials, caller infrastructure, and unrelated services/hosts remain untouched.

Implementation Notes

  • Likely surfaces: a new Python CLI module/entry point in crates/gf-bindings-py, a new @graphforge/cli package or intentionally expanded first-party npm CLI, shared Rust lifecycle/project-discovery APIs in gf-api/gf-storage, canonical skill sources under packages/agent-skills, package-build parity checks, and CLI integration fixtures.
  • Add a checked configuration schema/canonicalizer plus first-party Pulumi component packages and Terraform module/provider integration. Prefer one schema-generated contract over separately handwritten Python, Node, Pulumi, and Terraform models.
  • Reuse the existing project generation, capability, checkpoint, and complete-workspace revert contracts. Do not create a second persistence authority.
  • Ignore .graphforge/state/, .graphforge/imports/, and .graphforge/exports/ by default. Do not ignore the complete .graphforge/ namespace or its tracked project-definition siblings.
  • Use a recognizable managed .gitignore block or exact-line ownership rule so future update/removal is surgical.
  • Treat worktrees explicitly: each worktree gets its own default .graphforge/state/ unless a user provides an explicit safe external project path.

Observability

  • Emit bounded deterministic structured command results with operation type, outcome, selected repository-relative project identity, old/new generation identities where applicable, and Git commit/dirty status where available. Runtime duration belongs to CI/process observation rather than reproducible command receipts.
  • IaC validation/readiness output must distinguish desired configuration, static validation, planned infrastructure, deployed artifact identity, connectivity, health, and GraphForge capability compatibility so a green syntax check cannot be mistaken for a working service.
  • Do not emit absolute private paths by default in machine-readable errors; provide an explicit verbose human mode where safe.
  • No telemetry or network reporting is introduced by default. Any future telemetry remains separate and opt-in.

Security And Privacy

  • Defend against path traversal, archive traversal, symlink substitution, unsafe deletion targets, oversized/malformed artifacts, unsupported formats, capability downgrade, and confused repository-root selection.
  • Never scan or ingest secrets, ignored files, or the full worktree implicitly. sync inputs must be explicitly configured and honor documented ignore/boundary rules. External datasets remain outside the code repository and are addressed through explicit source manifests, stable identities, and integrity checksums.
  • Do not log graph payloads, exported values, credentials, diffs, or native exception text in error paths.
  • Preserve caller-owned operation, actor, provenance, graph, and knowledge identities; interactive convenience must not invent identities silently.
  • Treat Terraform state, Pulumi state, plan/preview output, and GraphForge resolved configuration as potential disclosure surfaces. Mark sensitive outputs correctly, redact bounded diagnostics, and test that secret sentinels never appear.

Testing

  • Rust unit/integration tests for discovery, boundary validation, atomic lifecycle behavior, import validation, checkpoint revert, and deletion target guards.
  • Python and Node contract tests over the same fixture matrix and golden --json outputs.
  • Clean-environment uvx and npx tests from packed/published-equivalent artifacts without a repository checkout.
  • Offline skill-install tests plus byte/manifest parity between Python and npm artifacts.
  • Real Git fixture tests for root/nested invocation, linked worktrees, absent and complex .gitignore, existing tracked state, dirty state, and filenames containing spaces/non-ASCII text.
  • Failure injection around export staging, import validation/publication, .gitignore update, skill installation/update conflicts, checkpoint revert, and removal.
  • Configuration-schema fixtures and golden resolved JSON shared across Rust/Python/Node/Pulumi/Terraform.
  • Pulumi preview/apply/destroy and Terraform validate/plan/apply/destroy acceptance over the same local/remote service/worker/job/host fixtures, including cross-language drift, incompatible artifact/locator input, secret-redaction, zero provider resources, and state-only teardown.
  • Map the eight BDD scenarios above to native integration tests plus clean-environment Python/Node and IaC acceptance runs.
  • Run the changed-surface gates and exact-head PR CI required by AGENTS.md; do not require unrelated release-only certification workflows for ordinary issue closure.

Documentation

  • Add a repository integration guide explaining the tracked .graphforge/ definitions and the ignored state/import/export data boundary, with an explicit rule that actual GraphForge and source data do not belong in the code repository.
  • Add and index the repository integration and deployment configuration ADR, cross-link it from the CLI/IaC guides, and cross-reference ADRs 0013, 0014, and 0015.
  • Add complete CLI reference pages for both invocation surfaces, exit codes, JSON contracts, explicit confirmation flags, preview behavior, and permanent state-removal semantics.
  • Add an IaC guide and configuration reference covering the schema, named targets, local/remote topology intent, Pulumi and Terraform usage, preview/plan rendering, artifact pins, secret/source references, caller-owned readiness, drift, and state-only destroy.
  • Document project-local skill destinations, compatibility/update policy, what should be committed, and host-specific adapters.
  • Update storage architecture, public API, agent-skills docs, examples, security guidance, and [Unreleased] changelog.

Non-Goals

  • Making the live .graphforge/state/ store Git-mergeable or recommending that it be committed.
  • Automatically committing, staging, untracking, pushing, opening PRs, or mutating GitHub.
  • Implementing or provisioning a remote GraphForge server, service/worker/host runtime, cloud resource, data-synchronization protocol, authentication transport, or distributed consensus. IaC output is a portable specification consumed by caller-owned infrastructure.
  • Inferring semantic merge behavior during import.
  • Replacing Rust-owned storage/checkpoint semantics with Python or Node implementations.
  • Installing global user-level skills by default.

Related Issues

Open Questions

  • Confirm npm registry availability of @graphforge/cli; if unavailable, choose another first-party package name without changing the shared command grammar.
  • Decide the exact portable export extension and schema identifier during implementation design; it must remain versioned and independent of the internal project layout.

Ontology lifecycle scope boundary

  • feat(api): add deterministic ontology suggestion, validation, and export #236 delivered the Rust API for runtime-catalog inspection, deterministic ontology suggestion, non-mutating validation, and explicit YAML/JSON ontology-document export.
  • feat(bindings): expose ontology lifecycle parity in Python and Node #237 delivered thin Python and Node parity over that Rust contract plus existing durable ontology adopt/clear behavior.
  • This tracker consumes those completed contracts when tracked ontology definitions participate in repository sync and whole-project portability. It does not reopen ontology inference, validation, authority, adoption, clearing, or document-export behavior.
  • The repository export/import commands remain whole-project portable interchange. They do not export an ontology document or infer ontology authority.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions