Skip to content

feat(sidecar): project_create, HIC-approved (v0.5.1 HGW-W3, runtime half) - #81

Closed
SaulBuilds wants to merge 3 commits into
hgw/w1-project-write-policyfrom
hgw/w1-project-create
Closed

SaulBuilds wants to merge 3 commits into
hgw/w1-project-write-policyfrom
hgw/w1-project-create

Conversation

@SaulBuilds

@SaulBuilds SaulBuilds commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

HGW Week 1, runtime, 3 of 5. Stack: #79 → #80 → this PR (base hgw/w1-project-write-policy) → #82 → #83. Green on its own. Refs CitrateNetwork/citrate-core#289 (HGW-W3), runtime half.

What changes

A sidecar-hosted tool, project_create {name, template?, params?}. It is offered to sessions with folder grants when CITRATE_HERMES_PROJECTS=1 (default off).

  1. Checked before anything is asked:

    • name is one plain folder name: letters, digits, ., _ and -; starts with a letter or digit; at most 64 characters; no .., no separators, no ~;
    • the projects root must exist and be under live read and write subtree grants;
    • <root>/<name> must not exist (an existing folder is never reused);
    • a template needs a configured renderer.
  2. HIC, always. One approval card (the feat(sidecar): taint escalates to HIC approval (v0.5.1 HGW-W1) #79 queue) shows the exact folder, template and parameters. Without an HIC-aware app nothing is created. In a tainted session the one card also carries the taint reason.

  3. On allow, with the grants checked again:

    A failed render removes the new folder and returns the renderer's error.

  4. Returns {ok, name, path, template, marker, rendered, note}.

Interface for the core lane

  • Environment, set when core starts the sidecar:
    • CITRATE_HERMES_PROJECTS=1;
    • CITRATE_HERMES_PROJECTS_ROOT=<abs>, default ~/Citrate/Projects;
    • for templates, CITRATE_HERMES_TEMPLATE_RENDERER=<abs path of citrate-templates> and CITRATE_HERMES_TEMPLATES_ROOT=<abs templates dir>;
    • CITRATE_HERMES_TEMPLATE_TIER=T0|T1|T2.
  • The template call (rendering stays core's). The TemplateRenderer trait is the seam. CliTemplateRenderer runs core's existing program:
    citrate-templates render --root <templates> --template <id> --tier <T> --out <new empty dir> [--param k=v]...
    It expects a JSON report on stdout with exit 0. It runs through the shell runner (argv only, scrubbed environment, 60 s timeout) inside the OS sandbox when there is one, writing only the new folder and reading the templates folder. Core must ship the binary (an externalBin, or the sidecar's resources).
  • Workspace grant (W3's first-use card): core creates ~/Citrate/Projects and grants it read and write (subtree). Without that, the tool says so and creates nothing.
  • Re-sending projects: keep each returned path and send it back in projectRoots (feat(sidecar,shell): project write policy, git in the sandbox (v0.5.1 HGW-W2) #80) on later sessions.

Needs a decision

core#289 plans project_create as a core-hosted Tauri tool that also runs git init in core and copies pinned libraries. This PR follows the runtime-lane brief instead (a sidecar tool; template rendering called from core). Pick one host. If core hosts it, leave CITRATE_HERMES_PROJECTS unset: the sidecar reserves the tool name when the switch is on, and a core tool with the same name would be refused at session create.

Library copying (W10) and git init are not done here. Git runs through shell_run, auto-approved in #83.

Tests (red first)

  • projects unit: +4 (name rules, parsing, env config, spec).
  • projects_tests: +10. Covers:
    • asks, then creates the folder and the marker, and the project is writable;
    • bad names are refused before asking;
    • no reuse of an existing folder;
    • the root must exist and be granted;
    • a decline creates nothing;
    • headless: nothing created;
    • tainted: one card;
    • template render, and cleanup after a failed render;
    • the CLI renderer's argv, also under real Seatbelt.
  • Workspace: 2268 → 2282 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_018wWZZ8GRVU9USh3kKQHsFe

SaulBuilds and others added 2 commits October 15, 2026 12:29
Hermes had no way to start a project: there was no default folder and
no tool to make one, and template rendering was a panel action only.

project_create {name, template?, params?} (sidecar-hosted, offered to
sessions with folder grants when CITRATE_HERMES_PROJECTS=1):
- name is one plain folder name (no separators, no `..`, no leading
  `.`/`-`/`~`, at most 64 chars); refused before anything is asked;
- the projects root (CITRATE_HERMES_PROJECTS_ROOT, passed by core;
  default ~/Citrate/Projects) must exist and be under live read+write
  subtree folder grants; <root>/<name> must not exist (never reused);
- always waits on an action card (HGW-1 queue) showing the exact folder
  and template; no HIC-aware app = nothing created; a tainted session
  shows one card carrying the taint reason;
- after approval (grants re-checked): creates the folder, renders the
  template if asked, writes .citrate/project.json, and makes the folder
  a session project root (HGW-2 build-config writes apply); a failed
  render removes the new folder and says why; returns the path.

Template rendering stays core's: the TemplateRenderer trait is the seam,
and CliTemplateRenderer runs core's `citrate-templates render --root
<templates> --template <id> --tier <T> --out <dest> [--param k=v]...`
(CITRATE_HERMES_TEMPLATE_RENDERER + CITRATE_HERMES_TEMPLATES_ROOT,
CITRATE_HERMES_TEMPLATE_TIER) through the shell runner, in the OS
sandbox when there is one, writing only the new folder.

Tests: projects unit (+4), projects_tests session/route (+10, incl. the
CLI renderer under real Seatbelt). Workspace: 2265 -> 2279 passed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wWZZ8GRVU9USh3kKQHsFe
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wWZZ8GRVU9USh3kKQHsFe

@BerryManifold BerryManifold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed project_create validation, unconditional per-action approval, live-grant recheck, no reuse of existing destinations, template argv handling and cleanup, marker creation, and project-root registration. All 14 project tests passed locally, including real Seatbelt renderer confinement. No new blocking finding in this PR. The owner ledger accepts runtime hosting. This is an incremental review; #80 remains blocked separately. CI rust failure was Chrome startup/DevTools timeouts, and audit failures require #85; a green rerun is still required.

@Matr0xshka Matr0xshka left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed project_create validation, unconditional per-action approval, live-grant recheck, no reuse of existing destinations, template argv handling and cleanup, marker creation, and project-root registration. All 14 project tests passed locally, including real Seatbelt renderer confinement. No new blocking finding in this PR. The owner ledger accepts runtime hosting. This is an incremental review; #80 remains blocked separately. CI rust failure was Chrome startup/DevTools timeouts, and audit failures require #85; a green rerun is still required.

…udit dependency updates, #85)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wWZZ8GRVU9USh3kKQHsFe
@SaulBuilds

Copy link
Copy Markdown
Contributor Author

Landed in main via #84 (squash 75e21cd), per the owner's 2026-10-15 decision to land the HGW stack #80–#84 as one squash. Reviewed and approved here.

@SaulBuilds SaulBuilds closed this Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants