Expand description
Project actions (03-01, PROJ-01/02): list with inheritance info, new, copy, rename, set (reparent), delete — serde models OUT, no printing (ARCHITECTURE.md layering: the Phase-6 TUI rides this same layer).
03-02 (PROJ-03/04) adds export/import: the export result carries
the static scope metadata (what a project ZIP does and does not
contain — roadmap criterion 4), and the import action owns the
collision policy — the abort pre-check refuses via project_find
BEFORE any upload; overwrite skips the pre-check (the server is
the authority) and dispatch guards it as destructive.
Two-column naming (LOCKED): client models stay wire-faithful; these action results re-expose the SELECTED fields under unit-explicit snake_case keys, ALL keys always present (null when absent) — the stable agent shape; agents must never key-hunt.
Every mutation READS BACK via project_find — the create/copy/
rename/modify response bodies are unverified LOW (the restart
literal true precedent), so the record the gateway answers with
IS the truth the CLI reports.
The parents/parents/{name} endpoints stay OUT of scope: the
server is the reparent authority (cycle guard), and PROJ-01’s
inheritance info comes from the list items themselves.
Structs§
- Export
Decoded Result ign project export --decode-scriptsoutput model (07-04, INTR-01): the DIRECTORY is the artifact — the export’s members plus<member>.<n>.pysidecars plus the pointer manifest, ready for nvim/ignition-lint editing.- Export
Result ign project exportoutput model:{project, file, bytes, scope}— the FILE is the artifact; stdout stays data-only.- Export
Scope - The scope metadata carried in BOTH export and import JSON data — identical consts, so the statement “what this ZIP does and does not contain” never drifts between the two commands.
- Import
Result ign project importoutput model:{name, collision_policy, bytes, scope, outcome}—outcomeis the opaque server answer (an object when JSON, else the success fallback).- NewOptions
project newflags — only provided fields ride the create body (absent = NOT SENT, Pitfall 5);enabledis the CLI--disabledflag inverted at the dispatch seam.- Project
Copy Result ign project copyoutput model: the source plus the destination’s read-back record (flat in JSON).- Project
Delete Result ign project deleteoutput model.- Project
Diff Result ign project diffoutput model — the flat agent shape, ALL keys always.scopeis the literal"project"(the scope-honesty mandate: tag providers live on a different seam, README documents the promotion pipe);profile_a/profile_bride the DATA while the envelope keeps its single active-profile field (the frozen one-field envelope).- Project
Meta Delta - One
project.jsonsemantic-field difference —(field, a, b)surfaced as named keys (the flat agent shape). - Project
Rename Result ign project renameoutput model: previous name plus the renamed project’s read-back record (flat).- Project
SetResult ign project setoutput model: the read-back record (flat, the stable agent shape) plus which fields this set touched — display-only, serde-skipped so it NEVER appears in JSON.- Project
Summary - One project row — the six fields PROJ-01 names.
- Project
Sync Result ign project syncoutput model — the flat agent shape, ALL keys always (empty vecs when none). Direction is ALWAYS explicit A→B (source A, target B).- Projects
Result ign project listoutput model.- SetOptions
project setflags — ONLY theSomefields ride the modify body (absent flag = don’t touch — Pitfall 5’s modify half).- Sync
Selection - What
project syncpromotes from A into B (07-01, SYNC-02) — at least one half is required (the CLI validates pre-resolution; the action re-validates for its other callers).
Enums§
- Collision
Policy - The import collision policy. REST exposes exactly abort and
overwrite —
mergeis the Designer import popup’s vocabulary and is rejected at the CLI value-enum level (README documents it as Designer-only).
Constants§
- EXPORT_
EXCLUDES - What a project export EXCLUDES — tag providers, tags, and UDTs are
GATEWAY CONFIGURATION, not project resources (the git-module
convention keeps a separate
tags/tree precisely because of this). - EXPORT_
INCLUDES - What a project export INCLUDES — the static, documented-once arrays (HIGH confidence: verified from a real git-module-managed 8.3 export tree). Data, not prose — agents key off them (roadmap criterion 4).
- IMPORT_
MAX_ BYTES - Import sanity limit — 512 MB (a real project export is MB-scale; anything past this is a wrong file, not a project). Checked BEFORE any network I/O.
Functions§
- project_
copy ign project copy— copy all resources, thenfind(to)read-back.- project_
delete ign project delete— the obedient arm; the--yesguard belongs to the CLI CALLER (it refuses pre-resolution, the LOCKED 02-03 shape). The wire request always carriesconfirm=true.- project_
diff ign project diff A B --project NAME— export both sides (A first), run the normalized member compare plus the project.json meta delta. A missing project on either side surfaces through export’s existing not-found path; the same profile twice is a usage-class refusal (exit 2) before any network I/O.- project_
export ign project export— stream the project ZIP to disk. With-othe bytes land at exactly that path; without one, the stream goes to<name>.zip.partin the working directory and atomically renames to the SANITIZEDContent-Dispositionbasename (path components stripped) or the<name>.zipfallback — the.partis removed best-effort on error, so a failed export leaves no half-written impostor.- project_
export_ decoded ign project export NAME --decode-scripts— buffer the export (the diff/sync seam), then decode the tree via the PURE codec: members + counter-named sidecars +scripts-manifest.jsonat the directory root. The re-encode half (import --encode-scripts) lives at the CLI dispatch seam — it re-zips the directory BEFORE this action’s import path, which then rides verbatim (validate_importwalks the re-zipped archive — the 05-07 guard applies free).- project_
import ign project import— order is the contract: magic/size guards (exit 2, zero network) → abort-policy find pre-check (Ok→CoreError::ProjectExistsBEFORE any upload) → the raw-body upload with the policy as the wire’soverwritequery param. Overwrite runs NO pre-check — the server is the authority — and the CLI guards it as destructive upstream of this action.- project_
new ign project new— create, thenfindread-back (validates the create and fills the result; the create response body itself is unverified LOW).- project_
rename ign project rename— native rename, thenfind(new)read-back.- project_
set ign project set— build the modify body fromSome-fields ONLY (absent flag = don’t touch), PUT, then read-back.--parentIS the inheritance move.- project_
sync ign project sync A B --project NAME— the guarded promotion. Order is the contract: export A then B → resolve the selection (explicit--resourcepaths must exist in A unless--deletewants them removed from B;--all_changedrides the diff) → splice A’s member bytes into B’s zip via the surgery helpers (replace_member’s descriptor-merge landing rules ride free — 05-07’s put-new hazard is handled) → optionalremove_memberpasses for deletions →validate_import+ ONE overwrite-import into B. B’s rootproject.jsonis never touched (only resource members splice). An EMPTY effective selection performs NO import (zero writes) and reports empty lists.- projects
ign project list— every runnable project with inheritance info (the standardlimit=-1UI convention).