devrites 4.0.1 → 4.0.2

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.
@@ -0,0 +1,167 @@
1
+ package release
2
+
3
+ import (
4
+ "archive/tar"
5
+ "bytes"
6
+ "compress/gzip"
7
+ "context"
8
+ "crypto/sha256"
9
+ "fmt"
10
+ "net/http"
11
+ "net/http/httptest"
12
+ "os"
13
+ "path/filepath"
14
+ "strings"
15
+ "testing"
16
+ )
17
+
18
+ func TestLatestAndAcquireVerifiedRelease(t *testing.T) {
19
+ const tag = "v4.1.0"
20
+ bundleName := "devrites-" + tag + ".tar.gz"
21
+ bundle := testBundle(t, tag, map[string]string{
22
+ "package.json": `{"version":"4.1.0"}`,
23
+ "pack/generated/claude/skills/rite/SKILL.md": "rite\n",
24
+ })
25
+ binaryName, err := platformBinaryName()
26
+ if err != nil {
27
+ t.Skip(err)
28
+ }
29
+ assets := map[string][]byte{
30
+ bundleName: bundle,
31
+ binaryName: []byte("test engine"),
32
+ }
33
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
34
+ if r.URL.Path == "/repos/owner/repo/releases/latest" {
35
+ _, _ = fmt.Fprintf(w, `{"tag_name":%q}`, tag)
36
+ return
37
+ }
38
+ name := filepath.Base(r.URL.Path)
39
+ if strings.HasSuffix(name, ".sha256") {
40
+ assetName := strings.TrimSuffix(name, ".sha256")
41
+ asset, ok := assets[assetName]
42
+ if !ok {
43
+ http.NotFound(w, r)
44
+ return
45
+ }
46
+ _, _ = fmt.Fprintf(w, "%x %s\n", sha256.Sum256(asset), assetName)
47
+ return
48
+ }
49
+ asset, ok := assets[name]
50
+ if !ok {
51
+ http.NotFound(w, r)
52
+ return
53
+ }
54
+ _, _ = w.Write(asset)
55
+ }))
56
+ defer server.Close()
57
+ oldAPI, oldWeb := apiBaseURL, webBaseURL
58
+ apiBaseURL, webBaseURL = server.URL, server.URL
59
+ t.Cleanup(func() { apiBaseURL, webBaseURL = oldAPI, oldWeb })
60
+
61
+ gotTag, err := Latest(context.Background(), "owner/repo")
62
+ if err != nil {
63
+ t.Fatal(err)
64
+ }
65
+ if gotTag != tag {
66
+ t.Fatalf("latest tag = %q, want %q", gotTag, tag)
67
+ }
68
+ candidate, cleanup, err := Acquire(context.Background(), "owner/repo", tag)
69
+ if err != nil {
70
+ t.Fatal(err)
71
+ }
72
+ root := filepath.Dir(candidate.SourceDir)
73
+ if _, err := os.Stat(filepath.Join(candidate.PayloadDir, "claude", "skills", "rite", "SKILL.md")); err != nil {
74
+ t.Fatalf("extracted payload: %v", err)
75
+ }
76
+ if got, err := os.ReadFile(candidate.EnginePath); err != nil || string(got) != "test engine" {
77
+ t.Fatalf("engine = %q, %v", got, err)
78
+ }
79
+ cleanup()
80
+ if _, err := os.Stat(root); !os.IsNotExist(err) {
81
+ t.Fatalf("cleanup kept %s: %v", root, err)
82
+ }
83
+ }
84
+
85
+ func TestValidTag(t *testing.T) {
86
+ for _, tc := range []struct {
87
+ tag string
88
+ want bool
89
+ }{
90
+ {tag: "v4.1.0", want: true},
91
+ {tag: "v4.1.0-rc.1+build.2", want: true},
92
+ {tag: "4.1.0", want: false},
93
+ {tag: "v4.1.0-01", want: false},
94
+ {tag: "v4.1", want: false},
95
+ } {
96
+ if got := validTag(tc.tag); got != tc.want {
97
+ t.Errorf("validTag(%q) = %t, want %t", tc.tag, got, tc.want)
98
+ }
99
+ }
100
+ }
101
+
102
+ func TestAcquireRejectsChecksumMismatch(t *testing.T) {
103
+ const tag = "v4.1.0"
104
+ bundleName := "devrites-" + tag + ".tar.gz"
105
+ bundle := testBundle(t, tag, map[string]string{
106
+ "package.json": `{"version":"4.1.0"}`,
107
+ "pack/generated/claude/skills/rite/SKILL.md": "rite\n",
108
+ })
109
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
110
+ if strings.HasSuffix(r.URL.Path, ".sha256") {
111
+ _, _ = fmt.Fprintf(w, "%064d %s\n", 0, bundleName)
112
+ return
113
+ }
114
+ _, _ = w.Write(bundle)
115
+ }))
116
+ defer server.Close()
117
+ oldWeb := webBaseURL
118
+ webBaseURL = server.URL
119
+ t.Cleanup(func() { webBaseURL = oldWeb })
120
+
121
+ _, _, err := Acquire(context.Background(), "owner/repo", tag)
122
+ if err == nil || !strings.Contains(err.Error(), "checksum mismatch") {
123
+ t.Fatalf("Acquire error = %v, want checksum mismatch", err)
124
+ }
125
+ }
126
+
127
+ func TestExtractBundleRejectsPathTraversal(t *testing.T) {
128
+ const tag = "v4.1.0"
129
+ archive := filepath.Join(t.TempDir(), "unsafe.tar.gz")
130
+ data := testBundle(t, tag, map[string]string{"../escape": "bad"})
131
+ if err := os.WriteFile(archive, data, 0o600); err != nil {
132
+ t.Fatal(err)
133
+ }
134
+ _, err := extractBundle(archive, t.TempDir(), tag)
135
+ if err == nil || !strings.Contains(err.Error(), "unsafe path") {
136
+ t.Fatalf("extractBundle error = %v, want unsafe path", err)
137
+ }
138
+ }
139
+
140
+ func testBundle(t *testing.T, tag string, files map[string]string) []byte {
141
+ t.Helper()
142
+ var raw bytes.Buffer
143
+ gz := gzip.NewWriter(&raw)
144
+ tw := tar.NewWriter(gz)
145
+ for name, body := range files {
146
+ data := []byte(body)
147
+ header := &tar.Header{
148
+ Name: "devrites-" + tag + "/" + name,
149
+ Mode: 0o644,
150
+ Size: int64(len(data)),
151
+ Typeflag: tar.TypeReg,
152
+ }
153
+ if err := tw.WriteHeader(header); err != nil {
154
+ t.Fatal(err)
155
+ }
156
+ if _, err := tw.Write(data); err != nil {
157
+ t.Fatal(err)
158
+ }
159
+ }
160
+ if err := tw.Close(); err != nil {
161
+ t.Fatal(err)
162
+ }
163
+ if err := gz.Close(); err != nil {
164
+ t.Fatal(err)
165
+ }
166
+ return raw.Bytes()
167
+ }
@@ -1,6 +1,6 @@
1
1
  package main_test
2
2
 
3
- // Cross-cutting assertion: first-party packages do not import forbidden network packages.
3
+ // Cross-cutting assertion: release acquisition is the only engine network boundary.
4
4
 
5
5
  import (
6
6
  "os/exec"
@@ -8,10 +8,9 @@ import (
8
8
  "testing"
9
9
  )
10
10
 
11
- // TestFirstPartyMakesNoNetworkCalls asserts that no first-party Go package imports
12
- // a forbidden network package. This keeps the engine a network-free control plane
13
- // that makes zero model/API calls (PRD: "zero API").
14
- func TestFirstPartyMakesNoNetworkCalls(t *testing.T) {
11
+ // TestNetworkImportsStayInReleaseBoundary keeps update networking isolated from
12
+ // workspace state, policy, proof, and installation logic.
13
+ func TestNetworkImportsStayInReleaseBoundary(t *testing.T) {
15
14
  if _, err := exec.LookPath("go"); err != nil {
16
15
  t.Skip("go toolchain unavailable")
17
16
  }
@@ -22,6 +21,7 @@ func TestFirstPartyMakesNoNetworkCalls(t *testing.T) {
22
21
  t.Fatalf("go list: %v", err)
23
22
  }
24
23
  forbidden := map[string]bool{"net": true, "net/http": true, "net/rpc": true, "net/smtp": true}
24
+ allowed := map[string]bool{"github.com/devrites/devrites/internal/release": true}
25
25
  for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
26
26
  fields := strings.Fields(line)
27
27
  if len(fields) == 0 {
@@ -29,7 +29,7 @@ func TestFirstPartyMakesNoNetworkCalls(t *testing.T) {
29
29
  }
30
30
  pkg, imports := fields[0], fields[1:]
31
31
  for _, imp := range imports {
32
- if forbidden[imp] {
32
+ if forbidden[imp] && !allowed[pkg] {
33
33
  t.Errorf("first-party package %s imports forbidden network package %q", pkg, imp)
34
34
  }
35
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "DevRites: a disciplined senior-engineer workflow pack for Claude Code and Codex",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://github.com/ViktorsBaikers/DevRites#readme",