Skip to content

release: promote frozen 0.6.5 beta candidate to stable - #226

Draft
makeitfutureDev wants to merge 225 commits into
mainfrom
release/0.7.0-20261106
Draft

makeitfutureDev wants to merge 225 commits into
mainfrom
release/0.7.0-20261106

Conversation

@makeitfutureDev

@makeitfutureDev makeitfutureDev commented Nov 6, 2026 •

Copy link
Copy Markdown
Owner

Prepare the 0.6.5 beta candidate for stable review. This draft is not ready for promotion: full AI acceptance remains incomplete, exact loaded production revision is unverified, and external QA connector authority currently blocks further live sends and Airtable writeback.

Candidate: 2c44e6cb1d308aef4f25f4eaf0f128b1af5c8ce6 (version 0.6.5; historical release branch name retains 0.7.0). The latest fix prevents Claude shell task lifecycle events from producing subagent progress. PR #242 was independently reviewed and landed on beta after all required PR checks passed.

Validation: all seven local gates passed, with 4,472 regression passes, 10 explicit opt-in skips, and 14 actual runtime passes. Tested head ae6effff6837603eff5e05d1a058a38dc5117852 and this candidate have identical tree df222ddc1093d043aa873c58f927a1c4e594e564. Exact-candidate CI, documentation and reboot workflows are separate checks; no prior-revision result is presented as their result.

Campaign has 639 active definitions / 1,037 matrix rows, with 605 verified immutable run records across revisions and eight additional prepared writebacks awaiting restored requester connector authority. Previous passes are historical evidence, not inherited exact-candidate acceptance. All eight campaign engine overrides and temporary Worker mutations have been restored and independently reread. Remaining native/external prerequisites and existing Teams/Google Chat holds stay visible; ten physical checks assigned to Flavius are explicitly deferred by the requester and are not passes.

No production restart or main/tag/release authorization is implied. Main promotion and publication require Tiberiu's explicit approval of the completed exact candidate.

tbiyss and others added 30 commits October 12, 2026 12:33
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Security audit follow-up, first batch (no functionality removed for anyone
acting within policy):

- Slack Settings mode control: only an organization admin can switch a
  channel INTO Admin mode (the rule /mode admin and set_channel_admin_mode
  already enforce). A channel manager keeps every other control in an
  Admin-mode channel and may step it down; the picker lists "Admin" only to
  an admin or when it is the current mode.
- Case-variant URLs: Express case-sensitive routing plus lowercase-aware
  path guards, so /API/settings is refused like /api/settings instead of
  slipping past the Host/Origin guard, the lockdown and the 401 branch.
- Security headers: nosniff, X-Frame-Options DENY and Referrer-Policy on
  every response; a no-inline-script Content-Security-Policy on the admin
  shell (import map admitted by content hash) and the login page, whose
  handler moves to public/login.js.
- One Express error handler (bare status, no stack trace), NODE_ENV=production
  in the systemd unit, /resume behind the admin session, constant-time
  compare of the internal IPC secret.
- Background-job "Check status" button gated like /status and scoped to its
  channel; status() reports the job's slug.
- File explorer share / send-to-me / preview / edit re-prove the opened file
  under the channel root (O_NOFOLLOW + /proc/self/fd), closing the
  symlink-swap race the agent-side export tools already closed.
- License card escapes platform-supplied text.
- npm audit fix: undici, zod, hono, fast-uri, body-parser, ip-address.

Tests: test/web-hardening.test.js (new), test/access-settings.test.js
(updated for the admin-only rule). FEATURES, TEST-PLAN and CHANGELOG updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
… policy to Settings runtime controls

Security audit follow-up, batch 4 (Slack access consistency):

- Narrowing a channel's use policy from "approved" to "admins" or "none"
  now drops the approved members that were seeded into allowedUsers under
  the "approved" policy, keeping only explicit (un-approved) guests. Done
  inside the same metadata transaction by both the Slack Access control
  (save notice with the count, channel_access_members_evicted audit event)
  and the admin UI channel meta PUT. Widening back re-admits nobody by
  itself; the org-wide reset still clears the whole list. isAuthorized and
  the seeding under "approved" are unchanged.
- The Slack Settings runtime controls (channel engine / model / effort,
  thread pins, thread reset) follow the gateway's model-change policy like
  /model, the wizard, the shortcuts and the platform controls: a DM owner
  always; elsewhere a non-admin only under the "users" policy. The page
  renders the current values with the policy line instead of pickers, and
  the handlers refuse a crafted payload before any write.

Tests: test/access-policy-eviction-web.test.js and
test/settings-runtime-policy.test.js (new), test/access-settings.test.js
(appended), test/channel-settings-modal.test.js (runtime option now follows
the policy). FEATURES, TEST-PLAN and CHANGELOG updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…l failures

Security audit follow-up, batch 3. `clientKey` (the identity the admin login
and approval-link backoffs bucket on) used to believe CF-Connecting-IP and
the FIRST X-Forwarded-For hop for any request on a loopback socket — which is
every request behind nginx, caddy, cloudflared or ssh -L. A caller could mint
a fresh bucket per request by writing its own header: unlimited online
password guessing plus a free scrypt per attempt.

- New setting `trustProxy` (Settings → Connection → "Behind a reverse proxy";
  env CG_TRUST_PROXY; the setting wins): "" trusts nothing (the socket is the
  client), "cloudflare" reads CF-Connecting-IP only, "xff" reads the LAST
  X-Forwarded-For hop (the proxy's, never the client's first one). Legacy
  CG_TRUST_PROXY=1 maps to "xff"; unknown values trust nothing and the admin
  API refuses them with 400.
- createLoginLimiter gains a key-independent global cap (default 50 failures
  per 10 minutes → every attempt waits the maximum delay until the window
  drains), injectable for tests and switchable off.
- The /approve limiter inherits both through the shared helper. Nothing else
  authorizes on forwarded headers; the Secure-cookie decision still reads
  x-forwarded-proto (it only ever makes the cookie stricter).
- docs/OPERATIONS.md and INSTALL.md: declare the proxy, or all remote logins
  share one backoff bucket.

Tests: web-security (clientKey per mode, settings/env precedence, global
cap), settings-save-version (route validation + UI wiring),
approval-links (end-to-end through the approve router with and without a
declared proxy). FEATURES, TEST-PLAN, CHANGELOG updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…ons)

Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…ns only or Locked

Only the seeded approved NON-admin members are evicted. Admins are admitted by
role under "Admins only", and under "Locked" the admin who locks the channel
must not lock themselves out of its Slack controls.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
A code channel is a dedicated Slack channel for one task, opened through
Slack's agents.conversations API only when the requester asks for it and
only after they confirm an approval card. It is registered as a child of
the origin channel: the origin's folder, access policy, secrets, skills,
engine and switches are re-projected onto it on every message and spawn,
while it keeps its own Slack identity, sessions and container.

The whole channel is one session (key `code-channel`, never a Slack ts),
so replies post top-level or in the thread a person used, the mention
gate admits every message there, the session status is addressed by
channel id without the legacy thread bridge, and a thread-less
agent_session_stopped sweeps everything running in the channel.

When the origin folder is a git repository the daemon creates branch
code/<slug> in a worktree at .worktrees/<slug> (from the upstream, else
the exact HEAD commit) and publishes its diff to the Code tab after each
turn, leaving out the gateway's managed instruction block; otherwise the
channel works in place. The requester may force either mode. The first
turn is started by the daemon with the task as the brief and the origin
thread as context. update_code_channel publishes html/block_kit/canvas/
pull_request tabs, context-bar items and the title; archive_code_channel
posts the wrap-up and archives behind an open-tier card.

Manifest: features.code_channels + the code_channels:manage scope.
Slack-only capability `codeChannels`; Slack-only guide reference.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…sections)

Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…es on public links

Security audit follow-up, batch 2.

Work-folder boundary (src/gateway/workdir-boundary.js): whatever the
allowlisted fsRoot admits, a channel's custom work folder may not be the
gateway account's home itself, the gateway runtime root or anything inside
it, ~/.ssh, ~/.claude, ~/.codex, the container engine's config or storage,
the hidden runtime artifact trees, the ChannelGate workspace root or one of
its platform folders, another conversation's work folder (default or
custom), or a parent of any of those. A subfolder of another conversation's
folder and the channel's own folders stay allowed. Enforced with a named
reason by set_channel_workdir, the admin UI workDir field and the runtime
resolver (an already-stored forbidden value fails every spawn closed with
the remedy); folder provisioning falls back to the default folder; one boot
warning per offending channel.

Protected export names: the shared export door (openConfinedFile) refuses a
hidden file or directory anywhere in the path, the managed .claude tree and
credential-shaped names, by requested AND physical path, for both public
link purposes, slack_share_file, Composio staging and previously minted
links. In-conversation previews (Slack explorer, Teams and Google Chat file
windows) are unchanged.

Two tests moved their custom work-folder fixtures beside the scratch gateway
root instead of under it, which is what the boundary now refuses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
… door

Keep functionality admins rely on while closing the audit holes:

- Another conversation's CUSTOM work folder (two channels on one repository),
  its parent and its subfolders stay allowed; only the gateway-made default
  folders, the gateway's own trees and the home itself are refused.
- The protected-name export policy gets two strengths: strict for public
  links (hidden paths, managed instruction/memory files, credential-shaped
  and secret-mentioning names) and lenient for slack_share_file, the footer
  download, Composio staging and mail attachments (hidden paths and
  credential-shaped files only), so MEMORY.md or a token-usage report can
  still be sent where an authorized person already reaches.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…c sections)

Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
@makeitfutureDev makeitfutureDev changed the title release: promote frozen 0.7.0 beta candidate to stable release: promote frozen 0.6.5 beta candidate to stable Nov 6, 2026
tbiyss added 29 commits November 6, 2026 17:50
…r-audit

Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>

This branch has not been deployed

No deployments
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.

2 participants