···8585 }
86868787 // Initialize operations handler
8888- ops, err := storage.NewOperations(config.Logger)
8888+ ops, err := storage.NewOperations(config.Logger, config.Verbose)
8989 if err != nil {
9090 return nil, fmt.Errorf("failed to initialize operations: %w", err)
9191 }
···471471 // Get hostname
472472 hostname, _ := os.Hostname()
473473474474- // ✅ Create BundleInfo
474474+ // Create BundleInfo
475475 bundleInfo := &storage.BundleInfo{
476476 BundleNumber: bundle.BundleNumber,
477477 Origin: origin,
···483483484484 m.logger.Printf("DEBUG: Calling operations.SaveBundle with bundle=%d", bundleInfo.BundleNumber)
485485486486- // ✅ Save to disk with 3 parameters
486486+ // Save to disk with 3 parameters
487487 uncompressedHash, compressedHash, uncompressedSize, compressedSize, err := m.operations.SaveBundle(path, bundle.Operations, bundleInfo)
488488 if err != nil {
489489 m.logger.Printf("DEBUG: SaveBundle FAILED: %v", err)
···15601560 if err := plcclient.ValidateDIDFormat(input); err != nil {
15611561 return "", 0, err
15621562 }
15631563- return input, 0, nil // ✅ No resolution needed
15631563+ return input, 0, nil // No resolution needed
15641564 }
1565156515661566 // Support did:web too
+1-1
bundle/metadata.go
···131131 }
132132 defer file.Close()
133133134134- // ✅ Use abstracted reader from storage package
134134+ // Use abstracted reader from storage package
135135 reader, err := storage.NewStreamingReader(file)
136136 if err != nil {
137137 return 0, 0, time.Time{}, time.Time{}, fmt.Errorf("failed to create reader: %w", err)
+1-1
bundle/scanner.go
···205205 for num := range jobs {
206206 path := filepath.Join(m.config.BundleDir, fmt.Sprintf("%06d.jsonl.zst", num))
207207208208- // ✅ NEW: Stream metadata WITHOUT loading all operations
208208+ // Stream metadata WITHOUT loading all operations
209209 meta, err := m.CalculateMetadataStreaming(num, path)
210210 if err != nil {
211211 results <- bundleResult{index: num, err: err}
+7-5
cmd/plcbundle/commands/common.go
···123123 config := bundle.DefaultConfig(absDir)
124124 config.AutoInit = opts.AutoInit
125125126126- // Set verbose from command if available
126126+ // Check BOTH global AND local verbose flags
127127 if opts.Cmd != nil {
128128- if verbose, err := opts.Cmd.Root().PersistentFlags().GetBool("verbose"); err == nil {
129129- config.Verbose = verbose
130130- }
128128+ globalVerbose, _ := opts.Cmd.Root().PersistentFlags().GetBool("verbose")
129129+ localVerbose, _ := opts.Cmd.Flags().GetBool("verbose")
130130+131131+ // Use OR logic: verbose if EITHER flag is set
132132+ config.Verbose = globalVerbose || localVerbose
131133 }
132134133135 // Create PLC client if URL provided
···146148 // Set handle resolver URL from flag or option
147149 handleResolverURL := opts.HandleResolverURL
148150 if handleResolverURL == "" && opts.Cmd != nil {
149149- handleResolverURL, _ = opts.Cmd.Root().PersistentFlags().GetString("handle-resolver") // ✅ Fixed flag name
151151+ handleResolverURL, _ = opts.Cmd.Root().PersistentFlags().GetString("handle-resolver")
150152 }
151153 // Only override default if explicitly provided
152154 if handleResolverURL != "" {
+10-8
cmd/plcbundle/commands/inspect.go
···255255 result.FileSize = info.Size()
256256257257 // Check for frame index
258258- ops := &storage.Operations{}
258258+ ops, _ := storage.NewOperations(nil, opts.verbose)
259259+259260 if _, err := ops.ExtractBundleMetadata(bundlePath); err == nil {
260261 result.HasFrameIndex = true // Has embedded index
261262 } else {
···274275 fmt.Fprintf(os.Stderr, "Reading embedded metadata...\n")
275276 metaStart := time.Now()
276277277277- ops := &storage.Operations{}
278278+ ops, _ := storage.NewOperations(nil, opts.verbose)
279279+278280 meta, err := ops.ExtractBundleMetadata(bundlePath)
279281 if err != nil {
280282 if opts.verbose {
···329331 fmt.Fprintf(os.Stderr, "Verifying cryptographic hashes...\n")
330332 verifyStart := time.Now()
331333332332- // ✅ Pass cmd parameter
334334+ // Pass cmd parameter
333335 result.ContentHashValid, result.CompressedHashValid, result.MetadataValid =
334336 verifyCrypto(cmd, bundlePath, result.Metadata, bundleNum, opts.verbose)
335337···352354// ============================================================================
353355354356func analyzeBundle(path string, opts inspectOptions) (*bundleAnalysis, error) {
355355- ops := &storage.Operations{}
357357+ ops, _ := storage.NewOperations(nil, opts.verbose)
356358 operations, err := ops.LoadBundle(path)
357359 if err != nil {
358360 return nil, err
···852854}
853855854856func verifyCrypto(cmd *cobra.Command, path string, meta *storage.BundleMetadata, bundleNum int, verbose bool) (contentValid, compressedValid, metadataValid bool) {
855855- ops := &storage.Operations{}
857857+ ops, _ := storage.NewOperations(nil, verbose)
856858857859 // Calculate actual hashes from file
858860 compHash, compSize, contentHash, contentSize, err := ops.CalculateFileHashes(path)
···867869 compressedValid = true
868870 metadataValid = true
869871870870- // ✅ Verify against embedded metadata if available
872872+ // Verify against embedded metadata if available
871873 if meta != nil {
872874 // Check content hash (this is in the metadata)
873875 if meta.ContentHash != "" && meta.ContentHash != contentHash {
···884886 metadataValid = true
885887 }
886888887887- // ✅ Note: We don't check compressed hash/size because they're not in metadata
889889+ // Note: We don't check compressed hash/size because they're not in metadata
888890 // (The file IS the compressed data, so it's redundant)
889891890892 if verbose {
···895897 }
896898 }
897899898898- // ✅ Also verify against repository index if bundle number is known
900900+ // Also verify against repository index if bundle number is known
899901 if bundleNum > 0 {
900902 mgr, _, err := getManager(&ManagerOptions{Cmd: cmd})
901903 if err == nil {
+3-10
cmd/plcbundle/commands/migrate.go
···148148 hashChanges := make([]int, 0, len(needsMigration))
149149150150 for i, bundleNum := range needsMigration {
151151- // ✅ Pass version to migrateBundle
151151+ // Pass version to migrateBundle
152152 if err := migrateBundle(dir, bundleNum, index, version, opts.verbose); err != nil {
153153 failed++
154154 if firstError == nil {
···172172 progress.Finish()
173173 elapsed := time.Since(start)
174174175175- // ✅ Update index with new compressed hashes
175175+ // Update index with new compressed hashes
176176 if len(hashChanges) > 0 {
177177 fmt.Printf("\nUpdating bundle index...\n")
178178 updateStart := time.Now()
···224224 fmt.Printf(" Index updated: %d entries\n", len(hashChanges))
225225 fmt.Printf(" Speed: %.1f bundles/sec\n\n", float64(success)/elapsed.Seconds())
226226227227- fmt.Printf("✨ New bundle format features:\n")
228228- fmt.Printf(" • Embedded metadata (JSON in skippable frame)\n")
229229- fmt.Printf(" • Frame offsets for instant random access\n")
230230- fmt.Printf(" • Multi-frame compression (100 ops/frame)\n")
231231- fmt.Printf(" • Self-contained (no .idx files)\n")
232232- fmt.Printf(" • Provenance tracking (version, origin, creator)\n")
233233- fmt.Printf(" • Compatible with standard zstd tools\n")
234227 } else {
235228 fmt.Printf("⚠️ Migration completed with errors\n")
236229 fmt.Printf(" Success: %d bundles\n", success)
···274267 // 4. Get hostname (optional)
275268 hostname, _ := os.Hostname()
276269277277- // 5. ✅ Create BundleInfo for new format
270270+ // 5. Create BundleInfo for new format
278271 bundleInfo := &storage.BundleInfo{
279272 BundleNumber: meta.BundleNumber,
280273 Origin: index.Origin, // From index