Skip to content

Commit 9b0eaa2

Browse files
Merge pull request #108 from makeitfutureDev/release/0.5.3
Release 0.5.3
2 parents 97f47c2 + d2dfcbc commit 9b0eaa2

155 files changed

Lines changed: 15569 additions & 1328 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ backup/
3333
.claude/skills/*
3434
.claude/worktrees/
3535
.agents/skills
36+
37+
# Chat-generated deliverables (reports, HTML explainers, presentations) written into the served
38+
# checkout by a channel turn. Output of the work, not source — and never a release artifact.
39+
/deliverables/

‎AGENTS.md‎

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ post/edit the reply in the thread (degraded to the surface's capabilities) → u
7878
the changed keys), `dead-fields.js` (retired fields stripped on every write).
7979
- `src/db/` — `index.js` (the one lazy `node:sqlite` connection: WAL, `busy_timeout`,
8080
`foreign_keys`, migrations on open, the one-time legacy JSON import behind `_meta` flags),
81-
`migrations.js` (versioned on `PRAGMA user_version`, currently 26 — append, never edit),
81+
`migrations.js` (versioned on `PRAGMA user_version`, currently 29 — append, never edit),
8282
`import-legacy.js`, `fts.js` (the optional FTS5 `channel_memory_fts` index; without FTS5 memory
8383
search degrades to a scan).
8484
- `src/gateway/run.js` — the run orchestrator: engine adapter selection and precedence (per-run
@@ -166,6 +166,16 @@ post/edit the reply in the thread (degraded to the surface's capabilities) → u
166166
`channel_instructions`) that never expire and re-post after a restart, and signed single-use
167167
browser links (`/approve/<token>`: GET decides nothing, POST decides exactly once and re-checks
168168
authority) for surfaces without Block Kit and for automation.
169+
- `src/gateway/ssh-access.js` + `ssh-broker.js` + `ssh-session.js` + `src/mcp/tools/ssh-access.js` — SSH access to
170+
channel containers (`docs/SSH-ACCESS.md`): the per-person key registry (`ssh_keys`), the
171+
per-channel `sshUsers` grant list, the host `authorized_keys` export (every line
172+
`restrict,command=`), the in-container sshd files, the session records (`ssh_sessions`), and the
173+
daemon's attach socket under `/var/lib/channelgate-ssh` (`CHANNELGATE_SSH_DIR`) — bound only
174+
once `scripts/install-ssh-access.sh` has set the host up. A session authorizes key → user →
175+
channel → grant → not operator-home-mounted, holds a container lease for its whole life, and
176+
pipes the developer's SSH stream into `exec -i <container> cg-sshd` (an unprivileged inetd-mode
177+
sshd in the image). `scripts/cg-ssh-attach.mjs` is the host wrapper (self-contained, copied
178+
root-owned by the installer). Nothing listens on a port anywhere.
169179
- `src/gateway/{updater,update-state,update-smoke,restart}.js` + `scripts/update-*` — the
170180
transactional self-update (the automatic path is an Enterprise entitlement; `scripts/update.sh`
171181
stays available to every operator): one durable transaction and lock, a detached built-ins-only
@@ -273,7 +283,8 @@ post/edit the reply in the thread (degraded to the surface's capabilities) → u
273283
(process-group kills), `process-outcome.js` (human descriptions of exits), `logger.js` (the
274284
`events` table), `timezone.js` (daemon-local time vs UTC containers), `cron.js`, `keyed-lock.js`,
275285
`singleton.js`, `drops.js`, `tail.js`.
276-
- `scripts/` — install and service (`install.sh`, `install-systemd.sh`, `install-whisper.mjs`),
286+
- `scripts/` — install and service (`install.sh`, `install-systemd.sh`, `install-ssh-access.sh` +
287+
`cg-ssh-attach.mjs` + `cg-ssh-authorized-keys`, `install-whisper.mjs`),
277288
updates (`update.sh` → `update-runner.mjs`), backup and restore (`backup-config.sh`,
278289
`restore-config.sh`, `restore-drill.sh`, `runtime-maintenance.mjs`), the image
279290
(`build-image.mjs`), the checks (`run-tests.mjs`, `static-check.mjs`, `secret-scan.mjs`,
@@ -311,7 +322,8 @@ through the control MCP.
311322
`thread_overrides`, `conversation_reply_sessions`, `active_runs`, `stopped_turns`,
312323
`inbound_events`, `teams_graph_subscriptions`); automation (`schedules`, `acks`,
313324
`followup_threads`, `followup_done`, `followup_digest_messages`, `bg_jobs`, `api_jobs`);
314-
approvals and questions (`approval_requests`, `approval_link_tokens`, `question_requests`); skills (`skills`, `skill_revisions`,
325+
approvals and questions (`approval_requests`, `approval_link_tokens`, `question_requests`); SSH
326+
access (`ssh_keys`, `ssh_sessions`); skills (`skills`, `skill_revisions`,
315327
`skill_revision_files`, `skill_sources`, `skill_templates`, `skill_usage`, `skill_proposals`,
316328
`skill_access_tokens`); Composio SDK (`composio_sessions`); licensing (`license_usage`);
317329
dashboard data (`usage`, `usage_components`, `usage_requests`, `usage_repair_batches`,
@@ -449,7 +461,14 @@ Config that stays as **files** (read wholesale / bootstrap, hand-editable):
449461
in. A run receives a RELAY of the resolved login's ACCESS token instead, gateway-owned and
450462
applied last in the child env so a channel secret cannot displace it. A turn with no resolvable
451463
login fails closed with the remedy named; it never runs on a guessed credential. A new consumer
452-
asks the resolver; it never adds a second notion of "the login".
464+
asks the resolver; it never adds a second notion of "the login". The ONE login file the gateway
465+
writes is an interactive SSH session's (`src/gateway/ssh-session.js`): an ACCESS-ONLY
466+
`.credentials.json` in the channel's config dir — the relayed token, its expiry and plan facts,
467+
never a refresh token, so it can rotate nothing — plus the operator's account record, both
468+
written through the relay, refreshed with it, and removed when the channel's last session ends.
469+
Claude Code labels a token in the environment "Claude API" and hides the plan, the usage windows
470+
and the plan's default model; only a file login shows them, which is what a developer in a
471+
terminal needs to see.
453472
- **Only admins get `--dangerously-skip-permissions`**, and only in an Admin-mode channel.
454473
Everyone else runs with the folder's `permissions.allow` allowlist and answers tool requests
455474
through the `permission_prompt` approval card (or Auto mode); headless can't answer interactive
@@ -489,6 +508,13 @@ Config that stays as **files** (read wholesale / bootstrap, hand-editable):
489508
including the `licenseAdmission()` call site in `src/gateway/run.js` and the `license_usage`
490509
schema — is a license violation and is sent back in review. Patches to that directory, new
491510
tiers or limits, and any licensing/CLA/trademark text change need a prior discussion.
511+
- **One worktree per task; never edit a shared checkout's working tree.** Several threads,
512+
schedules and background jobs run in the same folder, and two of them editing one working
513+
tree silently overwrite each other. Before the first edit of any task that touches a tracked
514+
file, open `.worktrees/<slug>` on its own branch from `origin/beta` and work only there; the
515+
shared checkout stays on `beta`, clean, and never changes branch. Uncommitted changes you did
516+
not write belong to another task — leave them and say so. Commands, landing and cleanup are
517+
under **One worktree per task** in Contributor workflow.
492518
- **Project records:** shipped behavior lives in `FEATURES.md`; the cumulative regression lives in
493519
`TEST-PLAN.md`. Keep both aligned with shipped code. Do not create, consult, or update
494520
`TASKS.md`, and do not make a brainstorming or standalone plan-writing phase a prerequisite for
@@ -503,6 +529,49 @@ Config that stays as **files** (read wholesale / bootstrap, hand-editable):
503529

504530
## Contributor workflow
505531

532+
### One worktree per task — before your first edit
533+
534+
**Never edit tracked files in a shared checkout's working tree.** Several threads, schedules and
535+
background jobs can run in the same folder at once, and two of them editing one working tree
536+
overwrite each other's uncommitted changes with no error and no trace. This is not a style
537+
preference and is not waived by a task being small, urgent, one file, or already started. The
538+
failure it prevents is real and has happened here: six unrelated features were built directly in
539+
the served checkout and left uncommitted, interleaved at hunk level across the same shared files,
540+
and could no longer be separated into the six commits they should have been.
541+
542+
Run this before the first edit of any task that creates, modifies or deletes a tracked file
543+
(read-only questions, status checks and analysis need none of it):
544+
545+
```sh
546+
git rev-parse --is-inside-work-tree # confirm this is the repo
547+
git fetch origin
548+
grep -qx '.worktrees/' .git/info/exclude 2>/dev/null || echo '.worktrees/' >> .git/info/exclude
549+
git worktree add -b <type>/<slug> .worktrees/<slug> origin/beta
550+
```
551+
552+
- Branch from `origin/beta` — never from `main`, and never from the shared checkout's current HEAD.
553+
- `<type>` is `feat`, `fix`, `docs`, `chore` or `test`; `<slug>` names the work. If the branch
554+
already exists, another task owns it: pick a different slug.
555+
- Keep worktrees in `.worktrees/` **inside** the repo folder, so they stay within the channel's
556+
mounted working folder. The `info/exclude` line keeps them out of `git status` without touching
557+
the tracked `.gitignore`.
558+
- Do every edit, test run and commit under `.worktrees/<slug>/…`, using paths inside the worktree
559+
rather than the matching path at the repo root. Commit early: only committed work survives a
560+
concurrent thread. Stage only your own files.
561+
- The shared checkout stays on `beta` and clean. Never switch its branch, and never edit its files
562+
while a task worktree is open.
563+
- One task, one worktree. Two features are two branches, even when they touch the same file — that
564+
is what keeps them separable later.
565+
566+
Land in the shared checkout (under the deployment's landing lock where one applies): bring `beta`
567+
current, `git merge --no-ff <type>/<slug>`, re-run a proportionate check after any conflict
568+
resolution, then push. Clean up only after `git merge-base --is-ancestor <type>/<slug> beta`
569+
succeeds, with `git worktree remove` followed by `git branch -d` — never `rm -rf` the directory,
570+
which leaves git's entry `prunable` and then blocks the branch delete.
571+
572+
If you find uncommitted changes in the shared checkout that you did not write, they are another
573+
task's work in progress. Leave them alone, say so in your reply, and open your own worktree.
574+
506575
### Beta development and stable promotion
507576

508577
- `beta` is the integration branch for all new development, fixes, documentation and tests.
@@ -533,8 +602,8 @@ Config that stays as **files** (read wholesale / bootstrap, hand-editable):
533602
defaults that say to merge completed tasks into `main`. Use the deployment's serialized landing
534603
lock for integration; never switch a shared served checkout to `main` merely to publish a release.
535604

536-
Use a dedicated branch and worktree from the latest upstream `beta`. Target development pull
537-
requests at `beta`; completed development work is merged and pushed to `beta`. Keep shared
605+
Open the task's own worktree first (see **One worktree per task** above; it is not optional).
606+
Target development pull requests at `beta`; completed development work is merged and pushed to `beta`. Keep shared
538607
integration checkouts clean, stage only your changes (never `git add -A` / `git commit -a`), write
539608
conventional imperative subjects, sign off every commit under `CLA.md` (`git commit -s`; the
540609
trailer is the CLA acceptance), and open a pull request with the design note and the actual check

0 commit comments

Comments
 (0)