Harden durable prompt state contracts

This commit is contained in:
2026-07-31 16:45:26 +00:00
parent 25782447eb
commit 870b54a4a0
5 changed files with 732 additions and 5 deletions

View File

@@ -247,9 +247,15 @@ func (s *FilesystemStore) PrepareRenderedReport(_ context.Context, resolved repo
}
func (s *FilesystemStore) SaveMetadata(_ context.Context, metadata Metadata) (string, error) {
if metadata.SchemaVersion != MetadataSchemaVersion {
return "", fmt.Errorf("new metadata must use schema version %q", MetadataSchemaVersion)
}
if err := metadata.Validate(); err != nil {
return "", err
}
if err := s.validateManagedPath("metadata path", metadata.MetadataPath); err != nil {
return "", err
}
if err := fileutil.WriteJSONAtomic(metadata.MetadataPath, metadata); err != nil {
return "", err
}
@@ -483,6 +489,28 @@ func (s *FilesystemStore) join(parts ...string) string {
return filepath.Join(all...)
}
func (s *FilesystemStore) validateManagedPath(name, path string) error {
if s == nil {
return fmt.Errorf("state store is required")
}
root, err := filepath.Abs(s.root)
if err != nil {
return fmt.Errorf("resolve workspace root: %w", err)
}
target, err := filepath.Abs(path)
if err != nil {
return fmt.Errorf("resolve %s: %w", name, err)
}
relative, err := filepath.Rel(root, target)
if err != nil {
return fmt.Errorf("resolve %s relative to workspace root: %w", name, err)
}
if relative == "." || relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
return fmt.Errorf("%s must stay within workspace root", name)
}
return nil
}
func validateRelativeDir(name string, value string) error {
if value == "" {
return fmt.Errorf("%s is required", name)