Commit Graph
116 Commits
Author SHA1 Message Date
Sycun 616726d452 feat: persist compaction checkpoints in the project blackboard 2026-10-11 23:08:54 +08:00
Sycun b841296f0e fix: snapshot MCP configuration and make tool deadline failures consistent 2026-10-09 10:58:12 +08:00
Sycun e8a5392b37 fix: serialize installation updates and recover interrupted adoption and rollback 2026-10-09 10:58:12 +08:00
Sycun 54d8f1187d fix: preserve rollback binaries during ambiguous recovery and YAML settings 2026-10-09 10:27:17 +08:00
Sycun 36e1d9680b fix: a version write keeps the document it lands in and the mode it had
Inserting `version` above a leading `---` put it in a document of its own, so
every setting after the marker parsed as a second document and was silently
ignored: the installation came up on defaults with a config that looked intact.
Both writers - the Go one and upgrade.sh's - now insert after the document
start, and the parse-back check still refuses anything a line rewrite cannot do
safely.

upgrade.sh rewrote config.yaml through a temp file created with the process
umask, so a 0600 config came back 0644 on every package upgrade - the file
holding the API keys became group/world readable. It now creates the temp file
privately and restores the original mode before the atomic replace.

A package upgrade also deleted `.update-build-pending`, because rsync --delete
only keeps what the exclude list names: the installation forgot a compile it
still owed and the next click reported "already up to date". Every one-click
update artifact is on the keep list now, asserted against .gitignore so the
next one cannot be forgotten the same way.
2026-10-08 22:46:29 +08:00
Sycun 81bd5f1a6e fix: the version writer recognizes every spelling its reader accepts
FileVersion reads the live config with the YAML parser, which understands
`"version":` and `'version':` exactly like the bare key. WriteVersion matched
lines by the literal prefix `version`, so a legal quoted-key config was not
recognized as already carrying the field at all: instead of replacing the line,
the writer prepended a second `version:` key. The file then failed to load
("mapping key \"version\" already defined"), i.e. the version sync could leave
an installation that no longer starts - while reporting success through the
real entry point (before=v1.0.0 -> after=v1.7.22, err=nil).

The writer now matches all three spellings, top-level only, first occurrence
only, and before writing it re-reads the new text with the same YAML parser: if
the result does not parse, or the top-level version does not read back as the
target, the write is refused and the original file is left byte-for-byte alone
(the update reports the skip and stands - a stale version number is a display
problem, a config that does not load is an installation that does not start).
Forms a line-based writer cannot rewrite, like JSON one-liners and block
scalars, are refused rather than corrupted.

The tarball path's writer in upgrade.sh gets the same rule set: top-level
three-spelling matching, first match only, a refusal for block/multi-line
scalars and for duplicate keys, plus the value validation the Go side applies -
a tag with a quote or newline in it can no longer reach the live config.

Regression tests: the config package covers the three quoted spellings and the
three refused forms (JSON one-liner, block scalar, duplicate key - file must
stay untouched), and the update package drives a quoted-key live config through
a real Apply and Rollback; the latter fails on the pre-fix tree with the
duplicate key it used to produce.
2026-10-08 16:16:21 +08:00
Sycun 0d931569be feat: carry the release version across an update, so the header matches the code
The repository's config.example.yaml ships the release version this code was cut
from (upstream bumps it in the release commit: v1.7.21's config.example says
v1.7.21), while the live config.yaml is operator data that no merge ever touches.
So after an update the header badge - and the ?v= on every static asset - kept
saying the version the installation was born with while the tree already ran
newer code.

An update, an adoption, or a rollback now keeps the two together: after the merge
the update reads the version the new code carries (config.example.yaml) and writes
it into the live config's version field - that one line, temp file plus atomic
rename, everything else byte-for-byte preserved, and only when the value actually
differs. The job log records the change (the page shows the step), and the state
file records both numbers so a rollback puts the old version back with the old
code; a number hand-edited after the update is the operator's and is left alone.
The side effect worth naming: the version bump also changes the ?v= query on
static assets, so a browser stops serving the pre-update JavaScript.

Trees without a live config or without a shipped version are left untouched -
a source checkout has nothing to sync, and nothing is ever guessed.

internal/config gains the two focused helpers (FileVersion / WriteVersion, line
level like the tarball upgrade path always did); tests pin the replace, the
insert-when-absent, byte preservation, the mode, the malformed-value refusal, and
the update/adopt/rollback/leave-alone behaviours end to end.
2026-10-08 13:57:11 +08:00
Sycun 94a18263b9 feat: make the update source one repository address, the official repo by default
The update source used to be three things - a remote name or an address, plus an
optional branch - and unset it followed whatever this directory's remotes and
upstream happened to say. That asked people to understand git topology before
they could update, and the person it was built for could not tell what "follow
the remote this tree tracks" meant. It is now one field: config.yaml update.repo,
an address, empty meaning the official repository
(https://github.com/AIPentest/CyberStrikeAI.git). Point it at a mirror (GitHub is
hard to reach in some places) or at your own fork and that is the whole
configuration.

The branch nothing is any more: an update follows the source repository's own
default branch, resolved from the source itself (ls-remote --symref HEAD), so a
fork whose default is not "main" still works and nobody has to name a branch.
Remote names, the mine/origin/upstream ranking, @{upstream} tracking and the
adopt flow's branch argument are all gone with it.

The console page loses two input fields: the source section is one address, a
hint that empty means the official repository, and a save button; clearing the
address is the way back to the default. The install facts drop the remote name,
the check section shows the source's default branch once the network answer
arrives, and the adopt entry no longer requires saving an address first - the
official default makes connecting a tarball install a zero-configuration action.

The CLI now reads the same update.repo field the page saves (LoadUpdateRepo reads
just that field, without validating the rest of the file - a broken unrelated
section must not block the path that fixes the tree), so the keyboard and the
button cannot update from different repositories. -check-update prints the source
it is about to use.

Tests: the source suite now pins the default (official), the single-address save
(including the empty-string reset), and that the followed branch comes from the
source's own default branch rather than a hardcoded "main"; the console suite
posts the one field and renders the default hint; docs, config.example.yaml and
upgrade.sh describe the one-field story.
2026-10-08 13:46:14 +08:00
Sycun acd84cd525 feat: let an installation choose its update source, and adopt a plain directory
config.yaml gains an optional update section (remote / remote_url / branch). The
resolver keeps its default - whatever remote this tree already tracks - and the
explicit choice wins when set, which is also what lets a tarball installation
that never saw git get on the update rails at all.

- RemoteURL is fetched straight into a ref namespace of its own, so a URL source
  cannot be shadowed by a same-named remote's stale refs. ValidRemoteURL allowlists
  https/http/ssh/git/file and local absolute paths, and rejects git's ext::
  transport (which executes commands) before anything reaches argv.
- Adopt connects a plain directory to the source. Preview is side-effect free (the
  fetch happens in a throwaway bare repository) and lists every local file whose
  content the target would replace, plus the operator content that is put aside.
  The confirmed run inits, adds origin, stashes operator content, keeps every
  replaced file under .update-backup/<ts>/overwritten/ so "the update ate my edit"
  has an address, lands the target content, sets upstream, rebuilds the binary.
  A failure removes only the .git it created itself; once the content has landed
  the tree stays adopted even if the build fails.
- Console/API: the status envelope carries the configured source;
  POST /system/update/source writes it through the same config path every other
  setting uses (validated, audited); POST /system/update/adopt is preview-then-job,
  with the job's kind recorded. OpenAPI updated; RBAC rides the existing
  update:apply prefix and the route inventory stays green.

Tests: URL-mode check/apply against real repositories (including the address
beating a remote name), URL validation table, and the full adoption story -
preview touches nothing, operator content survives, the replaced edit is in the
backup, and the adopted tree updates and rolls back like any other installation.
2026-10-07 12:46:32 +08:00
SycunandParallels 470eb5ead1 feat: add runtime storage cleanup with per-category retention (#310) (#313)
Runtime artifacts (agent workspaces, tool-output spill, C2 payloads, chat
uploads, workflow checkpoints, diagnostic logs) previously accumulated
without bound: most were only removed when a conversation or project was
deleted, and tmp/c2 plus workflow checkpoints were never removed at all.

Add a storage cleaner with named per-category tasks (Gitea-style), a
settings page tab, and a background sweep that is off by default so
upgrading never deletes existing data.

Safety properties, since mis-deleting live task data costs far more than
the disk saved:
- dry-run is the default; a real cleanup requires dry_run=false together
  with confirm=true at the API layer, not just a frontend dialog
- sessions active within active_grace_hours are always skipped, and a
  failed activity lookup skips conservatively (fail closed)
- directories whose conversation/project no longer exists are reclaimed
  as orphans after orphan_grace_days
- scanners never follow symlinks and every candidate path is confined to
  its category root; deletion renames to a .tmp-for-deletion marker first
  so a crash leaves recoverable residue instead of a half-deleted dir
- storage:* permissions are admin-only; without the grantSystemRolePermissions
  skip the default branch would have given operators an irreversible
  file-deletion right

Also fix two confirmed leaks: DeleteConversation left chat_uploads files
on disk (their rows already vanished via ON DELETE CASCADE), and workflow
checkpoints had no deletion path at all.

Co-authored-by: Parallels <parallels@kali-linux-2025-2.localdomain>
2026-09-25 14:46:23 +08:00
Ed1s0nZ bbfcb87103 fix: avoid duplicate summarization token limits 2026-09-23 18:02:00 +08:00
Ed1s0nZandCursor 38b96ec67a feat: add TypeSafe Jev as HITL audit backend
Let audit_agent approve or reject with one System One call instead of chat JSON, while keeping the OpenAI-compatible backend as an option.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 21:15:53 +08:00
Ed1s0nZ f7882be546 feat: manage task process lifetimes and preserve turn history 2026-09-16 17:52:58 +08:00
Ed1s0nZ 94cdf760af feat: persist diagnostic logs with daily rotation and retention 2026-09-08 14:41:46 +08:00
Ed1s0nZ 6ad9ea2d13 feat: add configurable tool call blocking and monitoring 2026-09-08 09:44:32 +08:00
temp d6d48c97c0 fix: normalize deepseek config profile 2026-08-25 18:37:08 +08:00
temp 21c6ad9bdf feat: persist hitl default config 2026-08-24 19:45:07 +08:00
temp baff533196 fix: disable chat checkpoint resume 2026-08-24 18:42:06 +08:00
temp d80e27e950 Respect OpenAI reasoning profile for DeepSeek-named models 2026-08-24 13:55:07 +08:00
公明 98c380ed5f Add files via upload 2026-08-18 20:31:48 +08:00
公明 55ee5fbac9 Delete internal directory 2026-08-18 20:14:29 +08:00
公明 7f8093f8b9 Add files via upload 2026-08-15 01:57:26 +08:00
公明 2910289f0b Delete internal directory 2026-08-15 01:54:26 +08:00
公明 e591fe4a9b Add files via upload 2026-08-15 01:36:02 +08:00
RuoJi6 aff9c9301f feat: refine HITL audit policy defaults (#236) 2026-08-05 18:02:48 +08:00
公明 0cd4df3518 Add files via upload 2026-07-23 19:00:54 +08:00
公明 4bbbe3bcf8 Add files via upload 2026-07-21 20:46:54 +08:00
公明 c2e1d37058 Add files via upload 2026-07-20 17:05:52 +08:00
公明 9a269ac0ec Add files via upload 2026-07-20 10:49:40 +08:00
公明 1858f4533a Add files via upload 2026-07-17 17:00:28 +08:00
公明 217f8f9648 Add files via upload 2026-07-17 10:53:24 +08:00
公明 295fa2ce74 Add files via upload 2026-07-14 16:10:37 +08:00
公明 515bde49a0 Add files via upload 2026-07-14 15:17:16 +08:00
公明 7d1e16b97b Add files via upload 2026-07-14 11:52:27 +08:00
公明 3c6cf633e1 Add files via upload 2026-07-11 11:44:25 +08:00
公明 2fcda3a57d Add files via upload 2026-07-11 10:47:04 +08:00
公明 478b52b011 Add files via upload 2026-07-10 21:23:33 +08:00
公明 cd87a0b965 Add files via upload 2026-07-10 18:47:30 +08:00
公明 a1201240d4 Add files via upload 2026-07-09 19:23:15 +08:00
公明 0531ee7292 Add files via upload 2026-07-09 11:33:15 +08:00
公明 bb4f239358 Add files via upload 2026-07-07 11:33:22 +08:00
公明 c84612211c Add files via upload 2026-07-07 10:17:03 +08:00
公明 a63b535a68 Add files via upload 2026-07-06 13:58:12 +08:00
公明 ebd872b373 Add files via upload 2026-07-03 16:57:09 +08:00
公明 745a69f93b Add files via upload 2026-07-03 14:12:20 +08:00
公明 2e063dd857 Add files via upload 2026-07-02 11:51:27 +08:00
公明 8dccc6aa06 Add files via upload 2026-07-01 10:44:27 +08:00
公明 e69fdb71ca Add files via upload 2026-06-30 20:11:54 +08:00
公明 ede32951bf Add files via upload 2026-06-30 19:52:30 +08:00
公明 553d0ed6bf Add files via upload 2026-06-30 17:59:02 +08:00