pwn 0.5.782 → 0.5.784

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -3
  3. data/Rakefile +19 -1
  4. data/bin/pwn_setup +1 -1
  5. data/build_gem.sh +1 -1
  6. data/documentation/Backup-Retention.md +27 -0
  7. data/documentation/Cron.md +64 -35
  8. data/documentation/How-PWN-Works.md +1 -1
  9. data/documentation/Installation.md +280 -15
  10. data/documentation/Persistence.md +1 -1
  11. data/documentation/Reinforcement-Learning.md +5 -6
  12. data/documentation/diagrams/cron-scheduling.svg +130 -128
  13. data/documentation/diagrams/dot/cron-scheduling.dot +3 -3
  14. data/documentation/pwn-REPL.md +31 -3
  15. data/documentation/pwn-ai-Agent.md +62 -2
  16. data/etc/default_cron/session_cleanup.rb +1544 -44
  17. data/lib/pwn/ai/agent/curriculum.rb +2 -2
  18. data/lib/pwn/ai/agent/extrospection.rb +6 -7
  19. data/lib/pwn/ai/agent/learning.rb +59 -11
  20. data/lib/pwn/ai/agent/mistakes.rb +22 -3
  21. data/lib/pwn/ai/agent/policy.rb +5 -0
  22. data/lib/pwn/ai/agent/swarm.rb +31 -16
  23. data/lib/pwn/ai/agent/tools/sessions.rb +6 -6
  24. data/lib/pwn/ai/http_retry.rb +3 -0
  25. data/lib/pwn/ai/router.rb +48 -3
  26. data/lib/pwn/cron.rb +120 -49
  27. data/lib/pwn/memory.rb +62 -6
  28. data/lib/pwn/migrate.rb +292 -15
  29. data/lib/pwn/plugins/binary_parser.rb +5 -4
  30. data/lib/pwn/plugins/ghidra.rb +4 -3
  31. data/lib/pwn/plugins/log.rb +18 -2
  32. data/lib/pwn/plugins/repl/ai.rb +25 -4
  33. data/lib/pwn/plugins/repl/ai_console.rb +41 -21
  34. data/lib/pwn/plugins/repl/ai_swarm.rb +4 -4
  35. data/lib/pwn/session_trace.rb +1 -1
  36. data/lib/pwn/sessions.rb +359 -92
  37. data/lib/pwn/setup.rb +9 -17
  38. data/lib/pwn/version.rb +1 -1
  39. data/scripts/build_gate.rb +58 -0
  40. data/spec/integration/build_gate_spec.rb +73 -0
  41. data/spec/integration/persistence_roundtrip_spec.rb +1 -7
  42. data/spec/lib/pwn/ai/agent/learning_spec.rb +65 -2
  43. data/spec/lib/pwn/ai/agent/policy_spec.rb +27 -0
  44. data/spec/lib/pwn/ai/agent/swarm_spec.rb +3 -3
  45. data/spec/lib/pwn/ai/router_spec.rb +30 -2
  46. data/spec/lib/pwn/cron_spec.rb +113 -6
  47. data/spec/lib/pwn/memory_spec.rb +58 -1
  48. data/spec/lib/pwn/migrate_spec.rb +160 -5
  49. data/spec/lib/pwn/plugins/log_spec.rb +7 -0
  50. data/spec/lib/pwn/plugins/repl/ai_console_spec.rb +203 -6
  51. data/spec/lib/pwn/plugins/repl/ai_result_chronology_spec.rb +2 -2
  52. data/spec/lib/pwn/plugins/repl/ai_spec.rb +28 -11
  53. data/spec/lib/pwn/plugins/repl/ai_swarm_spec.rb +11 -0
  54. data/spec/lib/pwn/redaction_spec.rb +13 -10
  55. data/spec/lib/pwn/session_cleanup_concurrency_spec.rb +201 -0
  56. data/spec/lib/pwn/session_cleanup_default_spec.rb +166 -3
  57. data/spec/lib/pwn/session_cleanup_legacy_spec.rb +101 -0
  58. data/spec/lib/pwn/session_cleanup_payload_spec.rb +800 -36
  59. data/spec/lib/pwn/session_cleanup_recovery_spec.rb +389 -0
  60. data/spec/lib/pwn/sessions_spec.rb +228 -16
  61. data/spec/lib/pwn/setup_spec.rb +3 -1
  62. data/spec/support/gate_failure_formatter.rb +14 -0
  63. data/third_party/pwn_rdoc.jsonl +27 -1
  64. metadata +14 -7
@@ -16,7 +16,7 @@ digraph "PWN_Cron" {
16
16
 
17
17
  Jobs [label="~/.pwn/cron/jobs.yml", shape=cylinder, fillcolor="#fcd34d"];
18
18
  Crontab [label="per-job crontab\n(install_crontab: true)", fillcolor="#fda4af"];
19
- Worker [label="background worker\npwn setup keep-alive\nsystemd --user / launchd\nschtasks / crontab @reboot", fillcolor="#fda4af"];
19
+ Worker [label="background worker\npwn setup starts/reuses\nportable internal scheduler\nhousekeeping: never systemd", fillcolor="#fda4af"];
20
20
  Runner [label="PWN::Cron.run(id)", fillcolor="#c4b5fd"];
21
21
 
22
22
  subgraph cluster_kinds {
@@ -29,7 +29,7 @@ digraph "PWN_Cron" {
29
29
  {rank=same; Prompt; Ruby; Script}
30
30
 
31
31
  subgraph cluster_seed {
32
- label="Seeded Jobs (install_defaults)"; fontcolor="#ddd6fe"; style=rounded;
32
+ label="Optional curriculum templates / preserved legacy jobs (NOT seeded)"; fontcolor="#ddd6fe"; style=rounded;
33
33
  color="#6d28d9"; bgcolor="#2e1065"; penwidth=2;
34
34
  Practice [label="curriculum_practice_nightly\n0 3 * * * OFF\nCurriculum.practice(limit:3)", fillcolor="#c4b5fd"];
35
35
  Offline [label="curriculum_offline_judge\n30 3 * * * OFF\nCurriculum.offline_judge", fillcolor="#c4b5fd"];
@@ -39,7 +39,7 @@ digraph "PWN_Cron" {
39
39
  }
40
40
  {rank=same; Practice; Offline; Train; MemGC; Lean}
41
41
 
42
- Cleanup [label="session_cleanup\n45 3 * * * ON\nleases / pins / backup before delete", fillcolor="#c4b5fd"];
42
+ Cleanup [label="ONLY fresh default: session_cleanup\n45 3 * * * ON (first-slot guard)\nevidence-first maintenance\nthen memory consolidation\nthen learning / mistakes / policy retention", fillcolor="#c4b5fd"];
43
43
  Ruby -> Cleanup; Cleanup -> Log;
44
44
  Log [label="~/.pwn/cron/log/<id>.log\nlast_run · last_status", shape=cylinder, fillcolor="#fcd34d"];
45
45
 
@@ -45,9 +45,37 @@ Aliases shared by multiple sessions are ambiguous too; use a stable ID.
45
45
  `dependencies` means **referenced by**: files containing defined structural
46
46
  references to that session. Transcript prose, prompts, tool results and quoted
47
47
  JSON—including previous `/sessions list` output—are not dependencies. An empty
48
- array means no known structural references; `dependency_errors` separately
49
- reports uncertainty and blocks scheduled cleanup. Dependency-backed sessions
50
- stay visible and resumable. See Installation's session-cleanup schema table.
48
+ array means no known structural references. `dependency_errors` contains only
49
+ errors attributed to this session; `unresolved_dependency_stores` reports global
50
+ uncertainty without assigning blame. Lists always include the current active
51
+ session, even while its title is provisional or summary generation failed.
52
+ Other rows require valid summary provenance or valid structural dependencies.
53
+ This display exception does not confer summary provenance or bypass cleanup:
54
+ activity leases still prevent physical deletion. Explicit resume remains available.
55
+ `/sessions list [offset] [limit]` defaults to the newest page, ordered oldest-first
56
+ within that page. An explicit offset starts at that oldest-first position.
57
+ The current session is marked `active: true` and included once even outside the
58
+ requested page (so at most limit + 1 rows). `total` counts unique visible sessions;
59
+ `offset` and `has_more` describe the base page, not the extra active row.
60
+ Global unresolved stores and specific diagnostics are reported once in the envelope.
61
+ Title workers capture the active provider/model when the request starts, summarize
62
+ only that session's persisted conversation, and retry on resume. Pending work is
63
+ coalesced per session rather than dropping another session's update. Failed or
64
+ invalid generation keeps the previous title and cursor, and reports a warning
65
+ without exposing provider payloads. It never fabricates `title_source: summary`.
66
+ `/sessions cleanup` applies the bundled cron maintenance operation; use
67
+ `/sessions cleanup --dry-run` for a read-only preview. Migration preserves full
68
+ redacted learning snapshots and their offline readers; it does not manufacture
69
+ lossless migrations for other stores. Unknown global ownership blocks apply.
70
+ Prepared/committed maintenance ledgers and recoverable backups live outside
71
+ ordinary backup pruning. Old writers must be quiesced before live deployment;
72
+ updating a helper alone does not update a running process.
73
+ Request checkpoints use a version-1, hash-bound identity adapter: their session
74
+ field is provenance because restore consumes the checkpoint itself. Unknown
75
+ versions, fields and mismatched paths remain unresolved; checkpoint bytes are
76
+ never rewritten by cleanup. Other unmigrated evidence edges remain retained.
77
+ `Sessions.list(include_hidden: true)` is the diagnostic inventory. See
78
+ Installation's session-cleanup schema table and remediation limitations.
51
79
  `title_source`, `is_summarized`, `classification` and `title_reason` expose the
52
80
  same strict provenance used by cleanup. Only persisted `summary` provenance with
53
81
  a nonblank summary/title and positive integer summary cursor counts as named.
@@ -39,8 +39,68 @@ The curses console exposes these local views through the command menu:
39
39
  Running phase checkpoints are atomically persisted before publication, including
40
40
  actual check records, uncovered requirements and repair reasons.
41
41
  Worktrees isolate edits, **not** arbitrary code execution or network access.
42
- * `/sessions cleanup` previews the same provenance/dependency policy as scheduled
43
- cleanup. Inspect the exact IDs, paths, fingerprints, retention reasons and
42
+ * `/sessions list [offset] [limit]` is a page, not a retention limit. The
43
+ envelope reports `returned`, visible `total`, `physical_sessions`,
44
+ `filtered_sessions`, `has_previous` and `has_more`, plus a disjoint root-entry
45
+ `storage` breakdown. Filtered transcripts remain physically retained and explicitly
46
+ resumable. Neither pagination nor layout migration deletes summarized sessions.
47
+ * Offline housekeeping migration is separate from ordinary cleanup. After deploying
48
+ matching source and stopping **all** launchers, workers and cron schedulers, run
49
+ from the checkout:
50
+
51
+ ```ruby
52
+ require 'pwn'
53
+ require './etc/default_cron/session_cleanup'
54
+ PWN::SessionCleanup.reorganize # metadata-only plan; no changes
55
+ PWN::SessionCleanup.reorganize(dry_run: false, writers_stopped: true)
56
+ PWN::SessionCleanup.run(dry_run: true) # inspect remaining retention categories
57
+ # Only after reviewing the ledger and approving cleanup:
58
+ PWN::SessionCleanup.run(dry_run: false)
59
+ ```
60
+
61
+ Launch Ruby with `bundle exec ruby -Ilib` so this uses matching source, not an
62
+ older installed gem. `writers_stopped` is an operator assertion, not a way to
63
+ bypass held leases or unknown legacy owners. Backups and prepared/committed
64
+ ledgers live in private `~/.pwn/session_cleanup_archive` directories. The layout
65
+ migration moves unreferenced metadata and lease inodes under `sessions/support`;
66
+ new trace support also uses that layout. Existing trace paths and dependency-backed
67
+ metadata stay at their exact locations to preserve evidence anchors and are
68
+ reported in `retained_support`. Canonical transcripts stay at the root. Abandoned numeric-PID transcript temp
69
+ files are removed only after exact recoverable backups in this offline operation.
70
+ Held own-process capability markers stay in place; other active owners block.
71
+ Readers accept legacy and compact paths, including partially completed moves.
72
+ Do not restart old binaries after applying the layout. Unknown files, mesh
73
+ mappings and request checkpoints remain untouched. Complete policy trajectories
74
+ are self-contained training provenance, not transcript-retention edges; incomplete
75
+ legacy trajectories and other unresolved evidence consumers still retain sources.
76
+ * Historical IDs are not automatically transcript dependencies. The shared index
77
+ validates self-contained Mistakes records (error/fix/counters), Memory reflection
78
+ values, Extrospection drift observations and Curriculum practice results before
79
+ treating their session IDs as provenance. These stores are not rewritten or
80
+ deleted by this classification. Incomplete records still pin their identified
81
+ source; malformed containers remain diagnostics. No summary or training label
82
+ is invented. Mistakes' previous-turn readers and Memory's session-turn reader
83
+ operate on the caller's current session, not historical occurrence IDs.
84
+ Curriculum's practice log is an audit log, not a replay/evaluation queue.
85
+ * Actual Learning transcript consumers retain full redacted, content-addressed
86
+ evidence through the existing migration before transcript deletion. Sessions.load,
87
+ Curriculum.offline_judge discovery and Reward PRM copy-on-write annotation use
88
+ the verified evidence; source hashes and complete source equality are checked
89
+ before releasing a live transcript. Overlapping provenance records no longer
90
+ prevent that preservation/re-index/deletion transaction.
91
+ * Swarm `personas.json` is different: `Swarm.ask` calls `persona_session`, which
92
+ reuses its ID and acquires a writable-session lease for `Loop.run`. `retire`
93
+ removes an agents.yml registration, not that association; an explicit persona
94
+ or later respawn can reuse it. There is no persisted association-completed or
95
+ retired-session marker. Neither old mtime, an absent registry name nor a
96
+ completed bus message proves a map obsolete. Such mappings remain protected,
97
+ even with a Learning snapshot, because a read-only training artifact is not a
98
+ writable continuation. Cleanup does not silently archive them or impose a cap.
99
+ * `/sessions cleanup` runs the same maintenance operation as bundled cron:
100
+ validate, preserve supported learning evidence, remediate attributable invalid
101
+ records with recoverable backups, re-index, and remove eligible inactive sessions.
102
+ `/sessions cleanup --dry-run` previews without changing evidence or deleting
103
+ sessions. Inspect the exact IDs, paths, fingerprints, retention reasons and
44
104
  uncertainty. `a`, then Enter confirms only the displayed candidate set.
45
105
  Newly discovered or changed records are excluded. Apply rechecks activity,
46
106
  references and source bytes under locks, backs up candidate bytes, and reports